Overview

Exploration of all the data collected on the presence points + randomly generated background points

A note to anyone who might happen to stumble across this… I am a beginner in R and have had no exposure to similar languages. I don’t know what I’m doing. The code herein is unlikely to be elegant and there are probably more efficient ways of running the code.

Built with ‘r getRversion()’.

Package dependencies

You can load them using the following code which uses a function called ipak. Note this function checks to see if the packages are installed first. The “include=FALSE” supresses the package installation text appearing in the document…

presence points

Read in the presence points

presence <- read.csv("../output/bio/presence_points_without_envdata_relooped_glbathy.csv", header = TRUE)
head(presence)

Update: Who sampled in which year and which month:

year

inst_by_yr <- with(presence, table(year, institutioncode))
write.csv(inst_by_yr, file = "../output/bio/institutioncode_by_yr.csv")
inst_by_yr
      institutioncode
year   ARC DFOCENARC DFOGulf DFOISDM DFOMTMS DFONL DFOQC MaineDMR NEFSC ROM
  1998   1         0      48       1      21   582     3        0     1   0
  1999   0         0      89       1      74   503     0        0     0   0
  2000  10         0      98       7      58   532     0        0     0   0
  2001   0         0      50       1      44   546     0        0     0   0
  2002   7         0     103       1      52   493     0        0     0   0
  2003   0         0      42       3      42   573     0        0     0   0
  2004   0         0      90       2      24   668   177        0     0   0
  2005   1        14     108       0      83   472   216        7     0   0
  2006   4        11      78       4      80   480   234        6     0   0
  2007   1        42      85       1      37   467   233        0     0   2
  2008   0        10      81       5      38   477   263        0     0   0
  2009   0        10      78       0      30   511   125        3     0   0
  2010   1        10      94       0      44   529   109        0     0   0
  2011   0        22      77       0      13   479   139        0     0   0
  2012   0         8      85       0      10     0   148        0     0   0
  2013   2        18      68       0      21     0   127        0     0   0
  2014   1        22     101       0       6     0     0        0     0   0
  2015   3        12       0       0       0     0     0        0     0   0

month

inst_by_mt <- with(presence, table(month, institutioncode))
write.csv(inst_by_mt, file = "../output/bio/institutioncode_by_mth.csv")
inst_by_mt
     institutioncode
month  ARC DFOCENARC DFOGulf DFOISDM DFOMTMS DFONL DFOQC MaineDMR NEFSC  ROM
   1     0         0       0       0       0   263     0        0     0    0
   2     0         0       0       0       7     4     0        0     0    0
   3     1         0       0       3     342     0     0        0     0    0
   4     0         0       0       3      11   732     0        0     1    0
   5     1         0       0       0       0  1106    17        8     0    0
   6     1         0       0       0       0  1694    24        3     0    0
   7    20        19       0      17     304    52    33        0     0    2
   8     1        73       7       1      14     0  1735        0     0    0
   9     8        23    1380       3       0     6    14        0     0    0
   10    0        63       5       3       0   545     2        2     0    0
   11    8         1       0       3       0  1811     0        3     0    0
   12    0         0       0       1       0  1136     0        0     0    0

environmental correlates

  1. Get the max, min, an mean values and add into a dataframe

Temperature

temp_depth_max <- max(presence$temp_depth, na.rm = TRUE)
temp_depth_min <- min(presence$temp_depth, na.rm = TRUE)
temp_depth_mean <- mean(presence$temp_depth, na.rm = TRUE)
temp_surface_max <- max(presence$temp_surface, na.rm = TRUE)
temp_surface_min <- min(presence$temp_surface, na.rm = TRUE)
temp_surface_mean <- mean(presence$temp_surface, na.rm = TRUE)

Salinity

sal_depth_max <- max(presence$salinity_depth, na.rm = TRUE)
sal_depth_min <- min(presence$salinity_depth, na.rm = TRUE)
sal_depth_mean <- mean(presence$salinity_depth, na.rm = TRUE)
sal_surface_max <- max(presence$salinity_surface, na.rm = TRUE)
sal_surface_min <- min(presence$salinity_surface, na.rm = TRUE)
sal_surface_mean <- mean(presence$salinity_surface, na.rm = TRUE)

Chl

chl_depth_max <- max(presence$chl_depth, na.rm = TRUE)
chl_depth_min <- min(presence$chl_depth, na.rm = TRUE)
chl_depth_mean <- mean(presence$chl_depth, na.rm = TRUE)
chl_surface_max <- max(presence$chl_surface, na.rm = TRUE)
chl_surface_min <- min(presence$chl_surface, na.rm = TRUE)
chl_surface_mean <- mean(presence$chl_surface, na.rm = TRUE)

O2

o2_depth_max <- max(presence$o2_depth, na.rm = TRUE)
o2_depth_min <- min(presence$o2_depth, na.rm = TRUE)
o2_depth_mean <- mean(presence$o2_depth, na.rm = TRUE)
o2_surface_max <- max(presence$o2_surface, na.rm = TRUE)
o2_surface_min <- min(presence$o2_surface, na.rm = TRUE)
o2_surface_mean <- mean(presence$o2_surface, na.rm = TRUE)

MLP

mlp_surface_max <- max(presence$mlp_surface, na.rm = TRUE)
mlp_surface_min <- min(presence$mlp_surface, na.rm = TRUE)
mlp_surface_mean <- mean(presence$mlp_surface, na.rm = TRUE)

SSH

ssh_surface_max <- max(presence$ssh_surface, na.rm = TRUE)
ssh_surface_min <- min(presence$ssh_surface, na.rm = TRUE)
ssh_surface_mean <- mean(presence$ssh_surface, na.rm = TRUE)

create matrix

td <- c(temp_depth_max, temp_depth_min, temp_depth_mean)
ts <- c(temp_surface_max, temp_surface_min, temp_surface_mean)
sd <- c(sal_depth_max, sal_depth_min, sal_depth_mean)
ss <- c(sal_surface_max, sal_surface_min, sal_surface_mean)
cd <- c(sal_depth_max, sal_depth_min, sal_depth_mean)
cs <- c(sal_surface_max, sal_surface_min, sal_surface_mean)
od <- c(o2_depth_max, o2_depth_min, o2_depth_mean)
os <- c(o2_surface_max, o2_surface_min, o2_surface_mean)
mlp <- c(mlp_surface_max, mlp_surface_min, mlp_surface_mean)
ssh <- c(ssh_surface_max, ssh_surface_min, ssh_surface_mean)
env_stats <- rbind(td, ts, sd, ss, cd, cs, od, os, mlp, ssh)
row.names(env_stats) <- c("Temp Depth", "Temp Surface", "Salinity Depth", "Salinity Surface", "Chl Depth", "Chl Surface", "Oxygen Depth", "Oxygen Surface", "MLP", "SSH") 
colnames(env_stats) <- c("Max", "Min", "Mean")
write.csv(env_stats, "../output/env/env_correlates_basic_stats.csv", row.names = TRUE)
env_stats
                         Max         Min        Mean
Temp Depth       289.0834045 271.2114868 274.9217164
Temp Surface     293.3608093 271.6101074 280.4476878
Salinity Depth    35.5045395  22.1449070  33.4295117
Salinity Surface  34.3667259  13.5929441  30.2518319
Chl Depth         35.5045395  22.1449070  33.4295117
Chl Surface       34.3667259  13.5929441  30.2518319
Oxygen Depth     377.2959595   0.9998450 279.6701444
Oxygen Surface   385.2262878 238.3178253 315.1620514
MLP              108.2339201  10.6823719  18.1911518
SSH               -0.2825949  -0.8503166  -0.5334292

Hmm some potentially suspicious values here in - Oxygen Depth min - mlp Max and maybe also - Salinity Depth min - Salinity Surface min - CHL depth min - CHL depth max

lets just see where these values appear and check the netcdf layers. Note I will check these values in cygwin using the cdo operator infov on the netcdfs (to ensure there was no issue with processing in R).

get the year and month these values appeared in

o2d_check_yr <- subset(presence$year, presence$o2_depth == o2_depth_min)
o2d_check_mth <- subset(presence$month, presence$o2_depth == o2_depth_min)

O2 depth min is in 2005_08

And value seems correct

mlp_check_yr <- subset(presence$year, presence$mlp_surface == mlp_surface_max)
mlp_check_mth <- subset(presence$month, presence$mlp_surface == mlp_surface_max)

mlp max in in 2007_12

And yes the value seems correct

sald_check_yr <- subset(presence$year, presence$salinity_depth == sal_depth_max)
sald_check_mth <- subset(presence$month, presence$salinity_depth == sal_depth_max)

year month 2001_05

also seems correct

sals_check_yr <- subset(presence$year, presence$salinity_surface == sal_surface_min)
sals_check_mth <- subset(presence$month, presence$salinity_surface == sal_surface_min)

year month 21998_06

ok again…

Leave the rest

simple plots of env. correlates

temperature

par(mfrow=c(1,2))
plot(presence$temp_depth, main = "Temp at Depth (Various)", ylab = "Kelvin")
plot(presence$temp_surface, main = "Temp at Surface", ylab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

Hmm not necessarily very helpful. But anyway, lets carry on

salinity

par(mfrow=c(1,2))
plot(presence$salinity_depth, main = "Salinity at Depth (Various)", ylab = "Practical Salinity Units")
plot(presence$salinity_surface, main = "Salinity at Surface", ylab = "Practical Salinity Units")
dev.copy(png,"../output/env/simple_plots/salinity_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

Chlorophyll

par(mfrow=c(1,2))
plot(presence$chl_depth, main = "Chl at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(presence$chl_surface, main = "Chl at Surface", ylab = "Chl (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/chl_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

O2

par(mfrow=c(1,2))
plot(presence$o2_depth, main = "Dissolved Oxygen at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(presence$o2_surface, main = "Dissolved Oxygen at Surface", ylab = "O2 (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/o2_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

mlp

plot(presence$mlp_surface, main = "Mixed Layer Thickness", ylab = "Depth (m)")
dev.copy(png,"../output/env/simple_plots/mlp_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

SSH

plot(presence$ssh_surface, main = "Sea Surface Height", ylab = "Height (m)")
dev.copy(png,"../output/env/simple_plots/ssh_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

XXX SAM - YOU WANT TO THINK ABOUT DOING THIS BY DEPTH RATHER THAN ALL DEPTHS)

unique_depths <- unique(presence$depthlayerno)
unique_depthdordered <- sort(unique_depths) #just puts the list in oder with no NA
length(unique_depthdordered)
[1] 39

ouch - 39 layers… a job for a boxplot probably

frequency plots of env. corr

temperature

hist(presence$temp_surface, main = "Temp at Surface", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(presence$temp_dept, main = "Temp at Depth", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

chl

hist(presence$chl_surface, main = "Chlorophyll at Surface", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(presence$chl_depth, main = "Chlorophyll at Observation Depth", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

salinity

hist(presence$salinity_surface, main = "Salinity at Surface", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(presence$salinity_depth, main = "Salinity at Observation Depth", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

oxygen

hist(presence$o2_surface, main = "Dissolved Oxygen at Surface", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(presence$o2_depth, main = "Dissolved Oxygen at Observation Depth", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

MLP

hist(presence$mlp, main = "Mixed Layer Thickness at Observation", xlab = "Mixed Layer Thickness (m)")
dev.copy(png, "../output/env/simple_plots/mlp_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ssh

hist(presence$ssh, main = "Sea Surface Height at Observation", xlab = "Sea Surface Height (m)")
dev.copy(png, "../output/env/simple_plots/ssh_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

simple boxplots of env. corr

Same as above but with boxplots (may provide some more useful info)

individual plots of each variable

par(mfrow=c(1,2))
boxplot(presence$chl_depth, main = "Chlorphyll at Depth (Various)", ylab = "mmol.m-3")
boxplot(presence$chl_surface, main = "Chlorphyll at Surface", ylab = "mmol.m-3")
dev.copy(png, "../output/env/simple_plots/chl_boxplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$temp_depth ~ presence$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$chl_depth ~ presence$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$salinity_depth ~ presence$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$o2_depth ~ presence$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/o2_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$mlp_surface ~ presence$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Observation per Month")
dev.copy(png, "../output/env/simple_plots/mlp_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$ssh_surface ~ presence$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Observation per Month")
dev.copy(png, "../output/env/simple_plots/ssh_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$temp_depth ~ presence$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$chl_depth ~ presence$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/chl_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$salinity_depth ~ presence$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$o2_depth ~ presence$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$mlp ~ presence$year, xlab = "Year", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Observation per Year")
dev.copy(png, "../output/env/simple_plots/mlp_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$ssh ~ presence$year, xlab = "Year", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Observation per Year")
dev.copy(png, "../output/env/simple_plots/ssh_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$temp_surface ~ presence$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$chl_surface ~ presence$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$salinity_surface ~ presence$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$o2_surface ~ presence$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/o2_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$mlp_surface ~ presence$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Observation per Month")
dev.copy(png, "../output/env/simple_plots/mlp_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$ssh_surface ~ presence$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Observation per Month")
dev.copy(png, "../output/env/simple_plots/ssh_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$temp_surface ~ presence$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$chl_surface ~ presence$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/chl_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$salinity_surface ~ presence$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$o2_surface ~ presence$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

background points

Read in the presence points

background <- read.csv("../output/bio/background_complete_obs_cels_globot.csv", header = TRUE)
head(background)

environmental correlates

  1. Get the max, min, an mean values and add into a dataframe

Temperature

temp_depth_max_back <- max(background$temp_depth, na.rm = TRUE)
temp_depth_min_back <- min(background$temp_depth, na.rm = TRUE)
temp_depth_mean_back <- mean(background$temp_depth, na.rm = TRUE)
temp_surface_max_back <- max(background$temp_surface, na.rm = TRUE)
temp_surface_min_back <- min(background$temp_surface, na.rm = TRUE)
temp_surface_mean_back <- mean(background$temp_surface, na.rm = TRUE)

Salinity

sal_depth_max_back <- max(background$salinity_depth, na.rm = TRUE)
sal_depth_min_back <- min(background$salinity_depth, na.rm = TRUE)
sal_depth_mean_back <- mean(background$salinity_depth, na.rm = TRUE)
sal_surface_max_back <- max(background$salinity_surface, na.rm = TRUE)
sal_surface_min_back <- min(background$salinity_surface, na.rm = TRUE)
sal_surface_mean_back <- mean(background$salinity_surface, na.rm = TRUE)

Chl

chl_depth_max_back <- max(background$chl_depth, na.rm = TRUE)
chl_depth_min_back <- min(background$chl_depth, na.rm = TRUE)
chl_depth_mean_back <- mean(background$chl_depth, na.rm = TRUE)
chl_surface_max_back <- max(background$chl_surface, na.rm = TRUE)
chl_surface_min_back <- min(background$chl_surface, na.rm = TRUE)
chl_surface_mean_back <- mean(background$chl_surface, na.rm = TRUE)

O2

o2_depth_max_back <- max(background$o2_depth, na.rm = TRUE)
o2_depth_min_back <- min(background$o2_depth, na.rm = TRUE)
o2_depth_mean_back <- mean(background$o2_depth, na.rm = TRUE)
o2_surface_max_back <- max(background$o2_surface, na.rm = TRUE)
o2_surface_min_back <- min(background$o2_surface, na.rm = TRUE)
o2_surface_mean_back <- mean(background$o2_surface, na.rm = TRUE)

MLP

mlp_surface_max_back <- max(background$mlp_surface, na.rm = TRUE)
mlp_surface_min_back <- min(background$mlp_surface, na.rm = TRUE)
mlp_surface_mean_back <- mean(background$mlp_surface, na.rm = TRUE)

SSH

ssh_surface_max_back <- max(background$ssh_surface, na.rm = TRUE)
ssh_surface_min_back <- min(background$ssh_surface, na.rm = TRUE)
ssh_surface_mean_back <- mean(background$ssh_surface, na.rm = TRUE)

create matrix

tdb <- c(temp_depth_max_back, temp_depth_min_back, temp_depth_mean_back)
tsb <- c(temp_surface_max_back, temp_surface_min_back, temp_surface_mean_back)
sdb <- c(sal_depth_max_back, sal_depth_min_back, sal_depth_mean_back)
ssb <- c(sal_surface_max_back, sal_surface_min_back, sal_surface_mean_back)
cdb <- c(sal_depth_max_back, sal_depth_min_back, sal_depth_mean_back)
csb <- c(sal_surface_max_back, sal_surface_min_back, sal_surface_mean_back)
odb <- c(o2_depth_max_back, o2_depth_min_back, o2_depth_mean_back)
osb <- c(o2_surface_max_back, o2_surface_min_back, o2_surface_mean_back)
mlpb <- c(mlp_surface_max_back, mlp_surface_min_back, mlp_surface_mean_back)
sshb <- c(ssh_surface_max_back, ssh_surface_min_back, ssh_surface_mean_back)
env_stats_back <- rbind(tdb, tsb, sdb, ssb, cdb, csb, odb, osb, mlpb, sshb)
row.names(env_stats_back) <- c("Temp Depth", "Temp Surface", "Salinity Depth", "Salinity Surface", "Chl Depth", "Chl Surface", "Oxygen Depth", "Oxygen Surface", "MLP", "SSH") 
colnames(env_stats_back) <- c("Max", "Min", "Mean")
write.csv(env_stats_back, "../output/env/env_correlates_background_basic_stats.csv", row.names = TRUE)
env_stats_back
                          Max         Min        Mean
Temp Depth        298.0517000 270.2798000 277.2492004
Temp Surface      298.2931000 271.0403000 278.9040097
Salinity Depth     36.2885400  12.8384380  33.3354335
Salinity Surface   35.9200800  12.0846500  32.3867768
Chl Depth          36.2885400  12.8384380  33.3354335
Chl Surface        35.9200800  12.0846500  32.3867768
Oxygen Depth      460.5706177   0.8061745 301.0655723
Oxygen Surface    410.5555000 207.4744000 315.9223887
MLP              2266.5013152   8.5859600  37.7989169
SSH                -0.1283472  -1.2465040  -0.6931972

temperature

par(mfrow=c(1,2))
plot(background$temp_depth, main = "Background Points Temp at Depth (Various)", ylab = "Kelvin")
plot(background$temp_surface, main = "Background Points Temp at Surface", ylab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 

salinity

par(mfrow=c(1,2))
plot(background$salinity_depth, main = "Background Points Salinity at Depth (Various)", ylab = "Practical Salinity Units")
plot(background$salinity_surface, main = "Background Points Salinity at Surface", ylab = "Practical Salinity Units")
dev.copy(png,"../output/env/simple_plots/salinity_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

Chlorophyll

par(mfrow=c(1,2))
plot(background$chl_depth, main = "Background Points Chl at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(background$chl_surface, main = "Background Points Chl at Surface", ylab = "Chl (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/chl_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

O2

par(mfrow=c(1,2))
plot(background$o2_depth, main = "Background Points Dissolved Oxygen at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(background$o2_surface, main = "Background Points Dissolved Oxygen at Surface", ylab = "O2 (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/o2_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

mlp

plot(background$mlp_surface, main = "Background Points Mixed Layer Thickness", ylab = "Depth (m)")
dev.copy(png,"../output/env/simple_plots/mlp_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

SSH

plot(background$ssh_surface, main = "Background Points Sea Surface Height", ylab = "Height (m)")
dev.copy(png,"../output/env/simple_plots/ssh_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

frequency plots of env. corr

temperature

hist(background$temp_surface, main = "Background Temp at Surface", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(background$temp_dept, main = "Background Temp at Depth", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

chl

hist(background$chl_surface, main = "Background Chlorophyll at Surface", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(background$chl_depth, main = "Background Chlorophyll at Observation Depth", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

salinity

hist(background$salinity_surface, main = "Background Salinity at Surface", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(background$salinity_depth, main = "Background Salinity at Observation Depth", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

oxygen

hist(background$o2_surface, main = "Background Dissolved Oxygen at Surface", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(background$o2_depth, main = "Background Dissolved Oxygen at Observation Depth", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

MLP

hist(background$mlp, main = "Background Mixed Layer Thickness at Observation", xlab = "Mixed Layer Thickness (m)")
dev.copy(png, "../output/env/simple_plots/mlp_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ssh

hist(background$ssh, main = "Background Sea Surface Height at Observation", xlab = "Sea Surface Height (m)")
dev.copy(png, "../output/env/simple_plots/ssh_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

simple boxplots of env. corr

Same as above but with boxplots (may provide some more useful info)

temperature

boxplot(background$temp_depth ~ background$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$chl_depth ~ background$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$salinity_depth ~ background$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$o2_depth ~ background$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/o2_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$mlp_surface ~ background$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Background per Month")
dev.copy(png, "../output/env/simple_plots/mlp_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$ssh_surface ~ background$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Background per Month")
dev.copy(png, "../output/env/simple_plots/ssh_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$temp_depth ~ background$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$chl_depth ~ background$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/chl_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$salinity_depth ~ background$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$o2_depth ~ background$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$mlp ~ background$year, xlab = "Year", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Background per Year")
dev.copy(png, "../output/env/simple_plots/mlp_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$ssh ~ background$year, xlab = "Year", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Background per Year")
dev.copy(png, "../output/env/simple_plots/ssh_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$temp_surface ~ background$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$chl_surface ~ background$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$salinity_surface ~ background$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$o2_surface ~ background$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/o2_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$mlp_surface ~ background$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Background per Month")
dev.copy(png, "../output/env/simple_plots/mlp_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$ssh_surface ~ background$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Background per Month")
dev.copy(png, "../output/env/simple_plots/ssh_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$temp_surface ~ background$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$chl_surface ~ background$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/chl_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$salinity_surface ~ background$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$o2_surface ~ background$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

correlations between background points

check to see if there are any correlations in the env. variables for the background points

first subset the env.correlate columns (you don’t need everything)

background_env <- subset(background, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
background_env_cor <- cor(background_env, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(background_env_cor, "../output/env/background_env_corr.csv", row.names = TRUE)
background_corrplot <- corrplot(background_env_cor , method = "color", type = "upper", order = "alphabet", tl.cex = 0.8) 
dev.copy(png,"../output/env/simple_plots/background_envcorr.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

to get some density plots all in one graphic, you need to change chunk output to in console, then go to the plot tab, make it fill the screen, then run then make bigger then save :( (probably a better way - this seems to be an issue with RStudio)

par(mfrow=c(4,4))
for(i in 1:16){
  plot(density(background_env[,i], na.rm=T), main = names(background_env)[i])
}

PUT THE CHUNK OUTPUT BACK TO INLINE

add nafo region and gear type into the mix

first subset the env.correlate columns + bottom_depth (you don’t need everything)

background_envbotdepth <- subset(background, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
background_envbotdepth_cor <- cor(background_envbotdepth, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(background_envbotdepth_cor, "../output/env/background_envbotdepth_cor.csv", row.names = TRUE)
background_corrplot <- corrplot(background_envbotdepth_cor , method = "color", type = "upper", order = "alphabet", tl.cex = 0.8) 
dev.copy(png,"../output/env/simple_plots/background_envbotdepth_cor.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

correlations between presence points

check to see if there are any correlations in the env. variables

first subset the env.correlate columns (you don’t need everything) then use cor to get the correlation values, and then corrplot for a visual

pres_env <- subset(presence, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
pres_env_cor <- cor(pres_env, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(pres_env_cor, "../output/env/pres_env_corr.csv", row.names = TRUE)
pres_corrplot <- corrplot(pres_env_cor , method = "color", type = "upper", order = "alphabet", tl.cex = 0.8) 
dev.copy(png,"../output/env/simple_plots/pres_envcorr.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

to get some density plots all in one graphic, you need to change chunk output to in console, then go to the plot tab, make it fill the screen, then run then make bigger then save :( (probably a better way - this seems to be an issue with RStudio)

graphics.off()
tiff("../output/env/simple_plots/background_envcorr_density.tiff") # to automatically save the plot to a png AND show it inline
par(mfrow=c(4,4), mar=c(1,1,1,1))
for(i in 1:16){
  plot(density(pres_env[,i], na.rm=T), main = names(pres_env)[i])
}
dev.off() # stops automatic saving of the plot to a png
null device 
          1 

PUT THE CHUNK OUTPUT BACK TO INLINE

density plot with background and presence env. data

Inspired by Merrow 2013 - top paragraph of page 1063 (are the species observations uniformly distributed over the background, or are they skewed)

ggplot(pres_env, aes(x = temp_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/temp_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = temp_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/temp_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = chl_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/chl_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = chl_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/chl_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = salinity_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/salinity_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = salinity_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/salinity_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = o2_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/o2_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = o2_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/o2_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = mlp_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/mlp_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = ssh_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/ssh_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

NAFO Regions

compare the environmental correlates between different NAFO regions

first see which nafo zones were sampled in each year

nafo_by_yr <- with(presence, table(year, nafo_zone))
write.csv(nafo_by_yr, file = "../output/bio/nafozone_by_yr.csv")
nafo_by_yr
      nafo_zone
year    0A  0B  1C  2G  2H  2J  3K  3L  3M  3N  3O 3Pn 3Ps  4R  4S  4T 4Vn 4Vs  4W  4X  5Y 5Ze HudsonStrait
  1998   0   0   0   0  12  56 113 230   0  44  69   3  58   0   0  70   9   7   4   3   1   0            0
  1999   0   0   0   0   0  35 103 212   0  45  50   2  60   0   0  87  11  35  28   2   2   0            0
  2000   0   0   0   0   0  55 116 238   2  52  53   4  48   0   0  99  12  26  20   1   0   0            0
  2001   0   0   0   0   3  35 126 214   0  52  56   2  61   0   0  52   6  28  11   0   0   0            0
  2002   0   0   0   0   0  36  71 214   0  50  62   4  60   0   0 110   8  28  16   1   0   0            0
  2003   0   0   0   0   0  50  66 232   0  63  76   3  89   0   0  44   8  20  15   1   0   0            0
  2004   0   0   0   0   8  60 209 194   0  58  66   7  69  40  70 160  10  11   5   1   0   0            0
  2005   0   7   0   7   0  49  92 198   0  37  54   1  42  50 112 166  27  23  30   4   7   0            0
  2006   3   4   0   3  14  49 175 178   0  25  26   0  19  28 132 148  11  39  31   9   7   1            0
  2007   0  13   0   3   0  36  84 173   0  56  57   1  62  28 122 172  10  19  11   0   1   0           26
  2008   3   7   0   0   6  49  82 162   0  46  57   0  77  64 129 157   5  18  13   3   0   2            0
  2009   0   0   0   1   0  45 100 172   0  54  67   8  66  18  63 130   7   1  23   0   3   0            9
  2010   0   9   1   0   6  34 111 207   0  62  63   3  50  16  56 134  12  18  14   0   0   0            0
  2011   0   9   0   1   5  36  80 161   0  70  51  12  64  32  58 127   7   6   2   0   0   0           12
  2012   0   7   0   1   0   0   0   0   0   0   0   0   0  34  71 133   5   1   3   1   0   0            0
  2013   0   3   0   6   1   0   0   2   0   0   0   0   0  27  58 113  15   2   4   0   0   0            8
  2014   1  16   0   1   0   0   0   1   0   0   0   0   0   0   0 101   6   0   0   0   0   0            4
  2015   0   8   0   1   0   0   0   2   0   0   0   0   1   0   0   0   0   0   0   0   0   0            3

and by month

nafo_by_mth <- with(presence, table(nafo_zone, month))
write.csv(nafo_by_mth, file = "../output/bio/nafozone_by_mth.csv")
nafo_by_mth
              month
nafo_zone         1    2    3    4    5    6    7    8    9   10   11   12
  0A              0    0    0    0    0    0    0    3    0    3    1    0
  0B              0    0    0    0    0    0    0   54   23    6    0    0
  1C              0    0    0    0    0    0    0    1    0    0    0    0
  2G              0    0    0    0    0    0   16    8    0    0    0    0
  2H              0    0    0    0    0    0    2    0    0   50    0    3
  2J              6    0    0    0    0    0    0    0    0  125  381  113
  3K            255    4    0    0    0    0    0    2    0    0  610  657
  3L              2    0    0    0  105 1410   83    1    0   64  764  361
  3M              0    0    0    0    0    0    0    0    0    2    0    0
  3N              0    0    0    0  308  254    0    0    0  110   40    2
  3O              0    0    0   28  522   31    1    0    6  194   24    1
  3Pn             0    0    0   42    8    0    0    0    0    0    0    0
  3Ps             0    0    0  662  163    0    0    0    0    0    1    0
  4R              0    0    0    0    0    0   18  318    1    0    0    0
  4S              0    0    0    0    2   10    5  852    2    0    0    0
  4T              0    0    0    0   15   14   10  570 1387    7    0    0
  4Vn             0    0    0    1    0    0  145    8   15    0    0    0
  4Vs             0    0  178    2    0    0   99    3    0    0    0    0
  4W              0    6  163   11    0    0   44    4    0    1    1    0
  4X              0    0    3    0    0    0   20    0    0    2    1    0
  5Y              0    0    0    1    9    3    3    0    0    2    3    0
  5Ze             0    1    2    0    0    0    0    0    0    0    0    0
  HudsonStrait    0    0    0    0    0    0    1    7    0   54    0    0

Interesting that there is a point in 1C - this is outside Canadian waters…. anyway

density plot with background and presence env. data by NAFO region

What I want to see if if there is a marked difference between the env. correlates of the presence points between NAFO regions. This is also to try deal with sampling bias (b/c the whole region is not uniformly sampled in each month, but rather nafo regions have a strong month bias)

first create NAFO-region datasets

nafo0a <- subset(presence, nafo_zone == "0A")
nafo0b <- subset(presence, nafo_zone == "0B")
nafo1c <- subset(presence, nafo_zone == "1C")
nafo2g <- subset(presence, nafo_zone == "2G")
nafo2h <- subset(presence, nafo_zone == "2H")
nafo2j <- subset(presence, nafo_zone == "2J")
nafo3k <- subset(presence, nafo_zone == "3K")
nafo3l <- subset(presence, nafo_zone == "3L")
nafo3m <- subset(presence, nafo_zone == "3M")
nafo3n <- subset(presence, nafo_zone == "3N")
nafo3o <- subset(presence, nafo_zone == "3O")
nafo3ps <- subset(presence, nafo_zone == "3Ps")
nafo4r <- subset(presence, nafo_zone == "4R")
nafo4s <- subset(presence, nafo_zone == "4S")
nafo4t <- subset(presence, nafo_zone == "4T")
nafo4vn <- subset(presence, nafo_zone == "4Vn")
nafo4vs <- subset(presence, nafo_zone == "4Vs")
nafo4w <- subset(presence, nafo_zone == "4W")
nafo4x <- subset(presence, nafo_zone == "4X")
nafo5Y <- subset(presence, nafo_zone == "5Ze")
nafohudson <- subset(presence, nafo_zone == "HudsonStrait")

plot by each variable, less 3m (2 samples) 1c (one sample) and 5ze (zero samples?!)

ggplot(nafo0a, aes(x = o2_depth, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/o2_depth_nafo.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

Let’s plot the variables by nafo region/year then by month

pr98 <- subset(presence, year == "1998")
boxplot(pr98$temp_depth ~ pr98$nafo_zone, xlab = "NAFO Region", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per NAFO Zone")
pr98 <- subset(presence, year == "1998")
pr11 <- subset(presence, year == "2011")
par(mfrow=c(2,1))
boxplot(pr98$temp_depth ~ pr98$nafo_zone, xlab = "NAFO Region", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per NAFO Zone")
boxplot(pr11$temp_depth ~ pr11$nafo_zone, xlab = "NAFO Region", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per NAFO Zone")

ok scrap the nafo region analysis - it is too mixed up with month (so seeing if region or month is a factor that needs to be factored in to the model is not appropriate)

remap who sampled

Now lets check the number of records and spatial-temporal distribution of the observations by institution code to make sure none are dodgy

first a table of how many observations each instituioncode has

obs_by_ins <- count(presence, "institutioncode")
obs_by_ins
write.csv(obs_by_ins, file = "../output/bio/samplinginstitutions/no_observations_institutioncode.csv")

ok so IMR, NAFO, ICES, & USM have very few entries (1, 1, 1, and 3 respectively)

Lets take a look at the spatial breakdown of these institutions.First all points…

map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(38, 70), asp = 1, main = "All Occurrences", col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(presence$decimalLongitude, presence$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/all_occurrences.png") #this prints a png of the plot
dev.off() #this turns off the print command

Note there is one point up by iceland that you should get rid of (Icelandic population thought to be seperate from Labrador, but it is unclear if this is true or not).

Map the institutioncode == ARC only data…

ARC_obs <- presence[presence$institutioncode == "ARC", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "Arc Occurrences", col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(ARC_obs$decimalLongitude, ARC_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/ARC_occurrences_all.png") #this prints a png of the plot
dev.off() #this turns off the print command

DFOCENARC_obs <- presence[presence$institutioncode == "DFOCENARC", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "DFO Central & Arctic Occurrences",  col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(DFOCENARC_obs$decimalLongitude, DFOCENARC_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/DFOCENARC_occurrences_all.png") #this prints a png of the plot
dev.off() #this turns off the print command

DFOGulf_obs <- presence[presence$institutioncode == "DFOGulf", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "DFO Gulf Occurrences",  col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(DFOGulf_obs$decimalLongitude, DFOGulf_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/DFOGulf_occurrences_all.png") #this prints a png of the plot
dev.off() #this turns off the print command

DFOISDM_obs <- presence[presence$institutioncode == "DFOISDM", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "DFO ISDM Occurrences",  col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(DFOISDM_obs$decimalLongitude, DFOISDM_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/DFOISDM_occurrences_all.png") #this prints a png of the plot
dev.off() #this turns off the print command

DFOMTMS_obs <- presence[presence$institutioncode == "DFOMTMS", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "DFO Maritimes Occurrences",  col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(DFOMTMS_obs$decimalLongitude, DFOMTMS_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/DFOMTMS_occurrences_all.png") #this prints a png of the plot
dev.off() #this turns off the print command

DFONL_obs <- presence[presence$institutioncode == "DFONL", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "DFO Newfouundland & Labrador Occurrences",  col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(DFONL_obs$decimalLongitude, DFONL_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/DFONL_occurrences_all.png") #this prints a png of the plot
dev.off() #this turns off the print command

DFOQC_obs <- presence[presence$institutioncode == "DFOQC", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "DFO Quebec Occurrences",  col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(DFOQC_obs$decimalLongitude, DFOQC_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/DFOQC_occurrences_all.png") #this prints a png of the plot
dev.off() #this turns off the print command

MaineDMR_obs <- presence[presence$institutioncode == "MaineDMR", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "Maine DMR Occurrences",  col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(MaineDMR_obs$decimalLongitude, MaineDMR_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/MaineDMR_occurrences_all.png") #this prints a png of the plot
dev.off() #this turns off the print command

NEFSC_obs <- presence[presence$institutioncode == "NEFSC", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "NEFSC Occurrences",  col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(NEFSC_obs$decimalLongitude, NEFSC_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/NEFSC_occurrences_all.png") #this prints a png of the plot
dev.off() #this turns off the print command

ROM_obs <- presence[presence$institutioncode == "ROM", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "Royal Ontario Museum Occurrences",  col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(ROM_obs$decimalLongitude, ROM_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/ROM_occurrences_all.png") #this prints a png of the plot

check for gear type

what are the unique gear types you have in your presence data, and how many?

so the vast majority are trawls of some type.

map the gear usage in Arcgis (gear_type_map)

create a table of gear use by month

gearby_mth
     gear
month bottom_trawl bottom_trawl_alfredo_03 bottom_trawl_campelen_14 bottom_trawl_campelen_1800 bottom_trawl_campelen_21 bottom_trawl_cosmos_2600 bottom_trawl_western_IIA unknown
   1             0                       0                        0                        263                        0                        0                        0       0
   2             7                       0                        0                          4                        0                        0                        0       0
   3           342                       0                        0                          0                        0                        0                        0       1
   4            12                       0                        0                        732                        0                        0                        0       0
   5             8                       0                        0                       1106                        0                        0                        0      18
   6             3                       0                        0                       1694                        0                        0                        0      25
   7           304                       0                       18                         64                        1                        0                        0      43
   8            14                       0                       34                       1193                       36                        3                        7     543
   9             0                       0                        0                         12                       23                        0                     1380      16
   10            2                       3                        0                        545                        0                       60                        5       2
   11            3                       0                        0                       1811                        0                        1                        0       8
   12            0                       0                        0                       1136                        0                        0                        0       0
     gear
month vertical_plankton_tow
   1                      0
   2                      0
   3                      3
   4                      3
   5                      0
   6                      0
   7                     17
   8                      1
   9                      3
   10                     3
   11                     3
   12                     1

What I want to see if if there is a marked difference between the env. correlates of the presence points between gear type used. This is also to try deal with detection bias between gear type (b/c the whole region is not uniformly sampled by the same gear type)

first create gear datasets

presence$gear <- as.character(presence$gear)
bottom_trawl <- subset(presence, gear == "bottom_trawl")
bottom_trawl_alfredo_03 <- subset(presence, gear == "bottom_trawl_alfredo_03")
bottom_trawl_campelen_14 <- subset(presence, gear == "bottom_trawl_campelen_14")
bottom_trawl_campelen_1800 <- subset(presence, gear == "bottom_trawl_campelen_1800")
bottom_trawl_campelen_21 <- subset(presence, gear == "bottom_trawl_campelen_21")
bottom_trawl_cosmos_2600 <- subset(presence, gear == "bottom_trawl_cosmos_2600")
bottom_trawl_western_IIA <- subset(presence, gear == "bottom_trawl_western_IIA")
unknown <- subset(presence, gear == "unknown")
vertical_plankton_tow <- subset(presence, gear == "vertical_plankton_tow")

plot by each variable, less 3m (2 samples) 1c (one sample) and 5ze (zero samples?!)

ggplot(bottom_trawl, aes(x = o2_depth, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/o2_depth_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

par(mar=c(7,5,1,1))
boxplot(presence$temp_depth ~ presence$gear, ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth by gear type", las = 2)
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_dept_gear.png") # to automatically save the plot to a png AND show it inline
dev.off() # stops automatic saving of the plot to a png

looks like not much difference… what about a kruskal wallace test?

kruskal.test(presence$temp_depth ~ presence$gear)

Ok so there is a statistically sig difference somewhere in the temp at depth reported by the gear type (Kruskal-Wallis chi-squared = 248.27, df = 7, p-value < 2.2e-16)

To see where the difference(s) are run a Dunn test Zar (2010) states that the Dunn test (in the FSA package) is appropriate for groups with unequal numbers of observations.(Zar, J.H. 2010. Biostatistical Analysis, 5th ed. Pearson Prentice Hall: Upper Saddle River, NJ.) http://rcompanion.org/rcompanion/d_06.html

SAM WHEN DUNN IS INSTALLED, GO TO RCOMPANIONS.ORG AND LOOK FOR DUNN - CHECK CHROME HISTORY (PROBABLY UNDER KRUSKAL WALLIS) ALSO MAP THE DISTRIBUTION OF THESE GEAR TYPES

pairwise.wilcox.test(presence$temp_depth, presence$gear, p.adj='bonferroni', exact=F)

dunn test

gear_temp_depthdunn <- dunnTest(presence$temp_depth, presence$gear, list = TRUE)
gear_temp_depthdunn



write.csv(table, "../output/env/gear_temp_depthdunn.csv", row.names = TRUE)

vif

for this you need the joined dataset. this was created under mergig_datasets.src and the file is ../output/bio/presab.csv

presab <- read.csv("../output/bio/presab.csv", header = TRUE)
vif_allpresab <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allpresab, "../output/bio/vif_allpresab.csv", row.names = TRUE)
vif_allpresab

interpret - see https://stats.stackexchange.com/questions/70679/which-variance-inflation-factor-should-i-be-using-textgvif-or-textgvif/96584#96584 To make GVIFs comparable across dimensions, we suggested using GVIF^(1/(2Df)), where Df is the number of coefficients in the subset (ref fox and motette 1992 in zotero) or the 2 continuous variables, GVIFˆ(1/(2Df)) (which is basically the square root of the VIF/GVIF value as DF=1) is the proportional change of the standard error and confidence interval of their coefficients due to the level of collinearity. The GVIFˆ(1/(2Df)) value of the categorical variable is a similar measure for the reduction in precision of the coefficients’ estimation due to collinearity. apparently i just need to square GVIF^(1/(2Df)) and then use the normal VIF “rule of thumb”…

vif_allpresab_sq <- read.csv("../output/bio/vif_allpresab.csv", header = TRUE)
vif_allpresab_sq$GVIF2Dfsq <- vif_allpresab_sq$GVIF..1..2.Df..^2
write.csv(vif_allpresab_sq, "../output/bio/vif_allpresab_sq.csv", row.names = TRUE)
vif_allpresab_sq

As per SLR suggestion, rerun without gear

vif_allbutgear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutgear, "../output/bio/vif_allbutgear.csv", row.names = TRUE)
vif_allbutgear

As per SLR suggestion, rerun without gear and most highly correlated variables

vif_allbutgearhighlycorr <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + bottom_depth + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbutgearhighlycorr, "../output/bio/vif_allbutgearhighlycorr.csv", row.names = TRUE)
vif_allbutgearhighlycorr

As per SLR suggestion, rerun with gear but without most highly correlated variables

vif_allbuthighlycorr <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + bottom_depth + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter + gear, data = presab))
write.csv(vif_allbuthighlycorr, "../output/bio/vif_allbuthighlycorr.csv", row.names = TRUE)
vif_allbuthighlycorr

vif_allbuthighlycorr_sq <- read.csv("../output/bio/vif_allbuthighlycorr.csv", header = TRUE)
vif_allbuthighlycorr_sq$GVIF2Dfsq <- vif_allbuthighlycorr_sq$GVIF..1..2.Df..^2
write.csv(vif_allbuthighlycorr_sq, "../output/bio/vif_allbuthighlycorr_sq.csv", row.names = TRUE)
vif_allbuthighlycorr_sq

ok remove one variable at a time - leave gear in

remove amo_prev

vif_allbutamo_prev <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbutamo_prev, "../output/bio/vif_allbutamo_prev.csv", row.names = TRUE)
vif_allbutamo_prev

vif_allbutamo_prev_sq <- read.csv("../output/bio/vif_allbutamo_prev.csv", header = TRUE)
vif_allbutamo_prev_sq$GVIF2Dfsq <- vif_allbutamo_prev_sq$GVIF..1..2.Df..^2
write.csv(vif_allbutamo_prev_sq, "../output/bio/vif_allbutamo_prev_sq.csv", row.names = TRUE)
vif_allbutamo_prev_sq

and leave gear out

remove amo_prev + gear

vif_allbutamo_prevgear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbutamo_prevgear, "../output/bio/vif_allbutamo_prevgear.csv", row.names = TRUE)
vif_allbutamo_prevgear

remove chl_depth

vif_allbutchl_depth <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutchl_depth, "../output/bio/vif_allbutchl_depth.csv", row.names = TRUE)
vif_allbutchl_depth

vif_allbutchl_depth_sq <- read.csv("../output/bio/vif_allbutchl_depth.csv", header = TRUE)
vif_allbutchl_depth_sq$GVIF2Dfsq <- vif_allbutchl_depth_sq$GVIF..1..2.Df..^2
write.csv(vif_allbutchl_depth_sq, "../output/bio/vif_allbutchl_depth_sq.csv", row.names = TRUE)
vif_allbutchl_depth_sq

remove chl_depth and gear

vif_allbutchl_depthgear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutchl_depthgear, "../output/bio/vif_allbutchl_depthgear.csv", row.names = TRUE)
vif_allbutchl_depthgear

remove ssh_surface

vif_allbutssh_surface <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutssh_surface, "../output/bio/vif_allbutssh_surface.csv", row.names = TRUE)
vif_allbutssh_surface

vif_allbutssh_surface_sq <- read.csv("../output/bio/vif_allbutssh_surface.csv", header = TRUE)
vif_allbutssh_surface_sq$GVIF2Dfsq <- vif_allbutssh_surface_sq$GVIF..1..2.Df..^2
write.csv(vif_allbutssh_surface_sq, "../output/bio/vif_allbutssh_surface_sq.csv", row.names = TRUE)
vif_allbutssh_surface_sq

remove ssh_surface & gear

vif_allbutssh_surfacegear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutssh_surfacegear, "../output/bio/vif_allbutssh_surfacegear.csv", row.names = TRUE)
vif_allbutssh_surfacegear

remove o2_surface

vif_allbuto2_surface <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuto2_surface, "../output/bio/vif_allbuto2_surface.csv", row.names = TRUE)
vif_allbuto2_surface

vif_allbuto2_surface_sq <- read.csv("../output/bio/vif_allbuto2_surface.csv", header = TRUE)
vif_allbuto2_surface_sq$GVIF2Dfsq <- vif_allbuto2_surface_sq$GVIF..1..2.Df..^2
write.csv(vif_allbuto2_surface_sq, "../output/bio/vif_allbuto2_surface_sq.csv", row.names = TRUE)
vif_allbuto2_surface_sq

remove o2_surface & gear

vif_allbuto2_surfacegear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuto2_surfacegear, "../output/bio/vif_allbuto2_surfacegear.csv", row.names = TRUE)
vif_allbuto2_surfacegear

as per SLR chat jan 23:

remove salinity_surface only

vif_allbutsalinitysurface <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutsalinitysurface, "../output/bio/vif_allbutsalinitysurface.csv", row.names = TRUE)
vif_allbutsalinitysurface

vif_allbutsalinitysurface_sq <- read.csv("../output/bio/vif_allbutsalinitysurface.csv", header = TRUE)
vif_allbutsalinitysurface_sq$GVIF2Dfsq <- vif_allbutsalinitysurface_sq$GVIF..1..2.Df..^2
write.csv(vif_allbutsalinitysurface_sq, "../output/bio/vif_allbutsalinitysurface_sq.csv", row.names = TRUE)
vif_allbutsalinitysurface_sq

and without gear

vif_allbutsalinitysurfacegear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutsalinitysurfacegear, "../output/bio/vif_allbutsalinitysurfacegear.csv", row.names = TRUE)
vif_allbutsalinitysurfacegear

now remove temp_surface plus highly correlated

#with gear
vif_allbuthighcorrtempsurface <- vif(lm(occurrence ~ temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + bottom_depth + mlp_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsurface, "../output/bio/vif_allbuthighcorrtempsurface.csv", row.names = TRUE)
vif_allbuthighcorrtempsurface

vif_allbuthighcorrtempsurface_sq <- read.csv("../output/bio/vif_allbuthighcorrtempsurface.csv", header = TRUE)
vif_allbuthighcorrtempsurface_sq$GVIF2Dfsq <- vif_allbuthighcorrtempsurface_sq$GVIF..1..2.Df..^2
write.csv(vif_allbuthighcorrtempsurface_sq, "../output/bio/vif_allbuthighcorrtempsurface_sq.csv", row.names = TRUE)
vif_allbuthighcorrtempsurface_sq

#without gear
vif_allbuthighcorrtempsurfacegear <- vif(lm(occurrence ~ temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + bottom_depth + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsurfacegear, "../output/bio/vif_allbuthighcorrtempsurfacegear.csv", row.names = TRUE)
vif_allbuthighcorrtempsurfacegear

now remove temp_surface plus salinity_surface

#with gear
vif_allbuttempsalsurface <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuttempsalsurface, "../output/bio/vif_allbuttempsalsurface.csv", row.names = TRUE)
vif_allbuttempsalsurface

vif_allbuttempsalsurface_sq <- read.csv("../output/bio/vif_allbuttempsalsurface.csv", header = TRUE)
vif_allbuttempsalsurface_sq$GVIF2Dfsq <- vif_allbuttempsalsurface_sq$GVIF..1..2.Df..^2
write.csv(vif_allbuttempsalsurface_sq, "../output/bio/vif_allbuttempsalsurface_sq.csv", row.names = TRUE)
vif_allbuttempsalsurface_sq

#without gear
vif_allbuttempsalsurfacegear <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuttempsalsurfacegear, "../output/bio/vif_allbuttempsalsurfacegear.csv", row.names = TRUE)
vif_allbuttempsalsurfacegear

now remove temp_surface plus salinity_surface + highly correlated

#with gear
vif_allbuthighcorrtempsalsurface <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + bottom_depth + mlp_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsalsurface, "../output/bio/vif_allbuthighcorrtempsalsurface.csv", row.names = TRUE)
vif_allbuthighcorrtempsalsurface

vif_allbuthighcorrtempsalsurface_sq <- read.csv("../output/bio/vif_allbuthighcorrtempsalsurface.csv", header = TRUE)
vif_allbuthighcorrtempsalsurface_sq$GVIF2Dfsq <- vif_allbuthighcorrtempsalsurface_sq$GVIF..1..2.Df..^2
write.csv(vif_allbuthighcorrtempsalsurface_sq, "../output/bio/vif_allbuthighcorrtempsalsurface_sq.csv", row.names = TRUE)
vif_allbuthighcorrtempsalsurface_sq

#without gear
vif_allbuthighcorrtempsalsurfacegear <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + bottom_depth + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsalsurfacegear, "../output/bio/vif_allbuthighcorrtempsalsurfacegear.csv", row.names = TRUE)
vif_allbuthighcorrtempsalsurfacegear

Just out of curiosity, a vif will all but but atmos drivers

vif_allbutnaoamo <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear, data = presab))
write.csv(vif_allbutnaoamo, "../output/bio/vif_allbutnaoamo.csv", row.names = TRUE)
vif_allbutnaoamo

vif_allbutnaoamo_sq <- read.csv("../output/bio/vif_allbutnaoamo.csv", header = TRUE)
vif_allbutnaoamo_sq$GVIF2Dfsq <- vif_allbutnaoamo_sq$GVIF..1..2.Df..^2
write.csv(vif_allbutnaoamo_sq, "../output/bio/vif_allbutnaoamo_sq.csv", row.names = TRUE)
vif_allbutnaoamo_sq

check to see how many cells have >1 point per timeslice

this needs to be 3D so you need to create a cell_id_3d

presab$cell_id_3d <- paste(presab$cell_id, presab$depthlayerno, sep="_") #create a new column that is a unique cell_id & depth ID. 
head(presab)

and now do one with a timeslice label

write.csv(presab, "../output/bio/../output/bio/presab_cellid_xyzt.csv", row.names = FALSE)
cannot open file '../output/bio/../output/bio/presab_cellid_xyzt.csv': No such file or directoryError in file(file, ifelse(append, "a", "w")) : 
  cannot open the connection

because background points can land in the same xyzt, subset the dataset to be only presences

presencedup <- subset(presab, occurrence == "1")
nrow(presencedup)
[1] 11393

the data is in presencedup$total_cell_obs_xyzt

unique_pointpercell <- unique(presencedup$total_cell_obs_xyzt)
unique_pointpercell
[1]  1  3  2  4  5  6 15

bugger… ok so lets do a frequency table

so there are 949 3d timesliced cells that contain more than one occurrence, and 2042 rows. - different sampling days - different coordinates - risk of duplicate entries (but only if two instituions inputted the same data with slightly different coordinates and different reserch program names - see cell3985_18_2000_7 below as example)

cell3985_18_2000_7  <- subset(celobsmore1, cell_id_xyzt == "3985_18_2000_7")
cell3985_18_2000_7 

Ideally you only want one observation cell cell_id_xyzt. First see if any are missing depth data

find the column numbers that correspond to the env. data (use fastmatch package as is quicker)

fmatch("chl_surface", names(celobsmore1)) #28
[1] 28
fmatch("chl_depth", names(celobsmore1)) #29
[1] 29
fmatch("mlp_surface", names(celobsmore1)) #30
[1] 30
fmatch("o2_surface", names(celobsmore1)) #31
[1] 31
fmatch("o2_depth", names(celobsmore1)) #32
[1] 32
fmatch("salinity_surface", names(celobsmore1)) #33
[1] 33
fmatch("salinity_depth", names(celobsmore1)) #34
[1] 34
fmatch("ssh_surface", names(celobsmore1)) #35
[1] 35
fmatch("temp_surface", names(celobsmore1)) #36
[1] 36
fmatch("temp_depth", names(celobsmore1)) #37
[1] 37

then subset any with NA values

celobsmore1_novals <-  celobsmore1[!complete.cases(celobsmore1[28:37]), ] #28:37 represent the columns w/ env. data
nrow(celobsmore1_novals) #just to check how many there are - 1095 out of 2042
[1] 1095

ok and subset with all values

celobsmore1_allvals <- celobsmore1[complete.cases(celobsmore1[28:37]), ] #28:37 represent the columns w/ env. data
nrow(celobsmore1_allvals) #947 out of 2042
[1] 947

ok so how many unique cells do we have with complete data…

pointpercellcount_alldata <- count(celobsmore1_allvals, "total_cell_obs_xyzt")
pointpercellcount_alldata$no_cells <- pointpercellcount_alldata$freq / pointpercellcount_alldata$total_cell_obs_xyzt
write.csv(pointpercellcount_alldata, file = "../output/bio/pointpercellcount_alldata.csv")
pointpercellcount_alldata

and see which cell_id_xyzt appear in both celobsmore1_allvals and celobsmore1_novals

celobsmore1_allnovals <- inner_join(celobsmore1_allvals, celobsmore1_novals)
Joining, by = c("cell_id", "year", "month", "depthlayerno", "id", "decimalLatitude", "decimalLongitude", "datecollected", "institutioncode", "individualcount", "depth", "resname", "originalscientificname", "collectioncode", "day", "occurrence", "nafo_zone", "gear", "longitude_meters", "latitude_meters", "amo_sample", "amo_prev", "amo_winter", "depth_layer", "bottom_depth", "total_cell_obs_xy", "total_cell_obs_xyt", "chl_surface", "chl_depth", "mlp_surface", "o2_surface", "o2_depth", "salinity_surface", "salinity_depth", "ssh_surface", "temp_surface", "temp_depth", "nao_sample", "nao_prev", "nao_winter", "total_cell_obs_xyzt", "temp_celsius_depth", "temp_celsius_surface", "bottom_depth_glorys", "cell_id_3d", "cell_id_xyzt")
celobsmore1_allnovals 

None…. which is good. I’d expect observations in the same xyzt to have the same values

so, I can successfully reduce the observations down to one per xyzt

obs_cell_yymm_depth_dup <- count(presab, cell_id, year, month, depthlayerno))
Error: unexpected ')' in "obs_cell_yymm_depth_dup <- count(presab, cell_id, year, month, depthlayerno))"

monthly spearmans correlations and VIF

curious - does correlations/vif alter between months?

First split the dataset into monthly

janpresab <- subset(presab, month == "1")
febpresab <- subset(presab, month == "2")
marpresab <- subset(presab, month == "3")
aprpresab <- subset(presab, month == "4")
maypresab <- subset(presab, month == "5")
junpresab <- subset(presab, month == "6")
julpresab <- subset(presab, month == "7")
augpresab <- subset(presab, month == "8")
seppresab <- subset(presab, month == "9")
octpresab <- subset(presab, month == "10")
novpresab <- subset(presab, month == "11")
decpresab <- subset(presab, month == "12")

now get the background points for each month (for spearmans)

janback <- subset(janpresab, occurrence == "0")
febback <- subset(febpresab, occurrence == "0")
marback <- subset(marpresab, occurrence == "0")
aprback <- subset(aprpresab, occurrence == "0")
mayback <- subset(maypresab, occurrence == "0")
junback <- subset(junpresab, occurrence == "0")
julback <- subset(julpresab, occurrence == "0")
augback <- subset(augpresab, occurrence == "0")
sepback <- subset(seppresab, occurrence == "0")
octback <- subset(octpresab, occurrence == "0")
novback <- subset(novpresab, occurrence == "0")
decback <- subset(decpresab, occurrence == "0")

run the correlations on each month’s background points

janback <- subset(janback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
janback_cor <- cor(janback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(janback_cor, "../output/env/janback_cor.csv", row.names = TRUE)

febback <- subset(febback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
febback_cor <- cor(febback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(febback_cor, "../output/env/febback_cor.csv", row.names = TRUE)

marback <- subset(marback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
marback_cor <- cor(marback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(marback_cor, "../output/env/marback_cor.csv", row.names = TRUE)

aprback <- subset(aprback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
aprback_cor <- cor(aprback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(aprback_cor, "../output/env/aprback_cor.csv", row.names = TRUE)

mayback <- subset(mayback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
mayback_cor <- cor(mayback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(mayback_cor, "../output/env/mayback_cor.csv", row.names = TRUE)

junback <- subset(junback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
junback_cor <- cor(junback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(junback_cor, "../output/env/junback_cor.csv", row.names = TRUE)

julback <- subset(julback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
julback_cor <- cor(julback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(julback_cor, "../output/env/julback_cor.csv", row.names = TRUE)

augback <- subset(augback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
augback_cor <- cor(augback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(augback_cor, "../output/env/augback_cor.csv", row.names = TRUE)

sepback <- subset(sepback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
sepback_cor <- cor(sepback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(sepback_cor, "../output/env/sepback_cor.csv", row.names = TRUE)

octback <- subset(octback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
octback_cor <- cor(octback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(octback_cor, "../output/env/octback_cor.csv", row.names = TRUE)

novback <- subset(novback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
novback_cor <- cor(novback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(novback_cor, "../output/env/novback_cor.csv", row.names = TRUE)

decback <- subset(decback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
decback_cor <- cor(decback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(decback_cor, "../output/env/decback_cor.csv", row.names = TRUE)

maxent?

library("raster")
library("dismo")
library("rgeos")
LS0tDQp0aXRsZTogIkRhdGEgRXhwbG9yYXRpb24iDQphdXRob3I6ICJTYW1hbnRoYSBBbmRyZXdzIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazogDQogICAgZmlnX2hlaWdodDogNw0KICAgIGZpZ193aWR0aDogMTANCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCiMgT3ZlcnZpZXcNCkV4cGxvcmF0aW9uIG9mIGFsbCB0aGUgZGF0YSBjb2xsZWN0ZWQgb24gdGhlIHByZXNlbmNlIHBvaW50cyArIHJhbmRvbWx5IGdlbmVyYXRlZCBiYWNrZ3JvdW5kIHBvaW50cw0KDQpBIG5vdGUgdG8gYW55b25lIHdobyBtaWdodCBoYXBwZW4gdG8gc3R1bWJsZSBhY3Jvc3MgdGhpcy4uLiBJIGFtIGEgYmVnaW5uZXIgaW4gUiBhbmQgaGF2ZSBoYWQgbm8gZXhwb3N1cmUgdG8gc2ltaWxhciBsYW5ndWFnZXMuIEkgZG9uJ3Qga25vdyB3aGF0IEknbSBkb2luZy4gVGhlIGNvZGUgaGVyZWluIGlzIHVubGlrZWx5IHRvIGJlIGVsZWdhbnQgYW5kIHRoZXJlIGFyZSBwcm9iYWJseSBtb3JlIGVmZmljaWVudCB3YXlzIG9mIHJ1bm5pbmcgdGhlIGNvZGUuDQoNCkJ1aWx0IHdpdGggJ3IgZ2V0UnZlcnNpb24oKScuDQoNCiMgUGFja2FnZSBkZXBlbmRlbmNpZXMNCllvdSBjYW4gbG9hZCB0aGVtIHVzaW5nIHRoZSBmb2xsb3dpbmcgY29kZSB3aGljaCB1c2VzIGEgZnVuY3Rpb24gY2FsbGVkIFtpcGFrXShodHRwczovL2dpc3QuZ2l0aHViLmNvbS9zdGV2ZW53b3J0aGluZ3Rvbi8zMTc4MTYzKS4gDQpOb3RlIHRoaXMgZnVuY3Rpb24gY2hlY2tzIHRvIHNlZSBpZiB0aGUgcGFja2FnZXMgYXJlIGluc3RhbGxlZCBmaXJzdC4NClRoZSAiaW5jbHVkZT1GQUxTRSIgc3VwcmVzc2VzIHRoZSBwYWNrYWdlIGluc3RhbGxhdGlvbiB0ZXh0IGFwcGVhcmluZyBpbiB0aGUgZG9jdW1lbnQuLi4NCmBgYHtyIHByZS1pbnN0YWxsIHBhY2thZ2VzLCBpbmNsdWRlPUZBTFNFfQ0KcGFja2FnZXMgPC0gYygicGx5ciIsICJncmFwaGljcyIsICJnZ3Bsb3QyIiwgImNvcnJwbG90IiwgIkZTQSIsICJjYXIiLCAicndvcmxkbWFwIiwgImZhc3RtYXRjaCIpIA0Kc291cmNlKCIuLi9zcmMvaXBhay5SIikNCmlwYWsocGFja2FnZXMpDQpgYGANCg0KDQojIHByZXNlbmNlIHBvaW50cw0KUmVhZCBpbiB0aGUgcHJlc2VuY2UgcG9pbnRzDQoNCmBgYHtyfQ0KcHJlc2VuY2UgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vcHJlc2VuY2VfcG9pbnRzX3dpdGhvdXRfZW52ZGF0YV9yZWxvb3BlZF9nbGJhdGh5LmNzdiIsIGhlYWRlciA9IFRSVUUpDQpoZWFkKHByZXNlbmNlKQ0KYGBgDQoNCiMjIFVwZGF0ZTogV2hvIHNhbXBsZWQgaW4gd2hpY2ggeWVhciBhbmQgd2hpY2ggbW9udGg6DQoNCnllYXINCmBgYHtyfQ0KaW5zdF9ieV95ciA8LSB3aXRoKHByZXNlbmNlLCB0YWJsZSh5ZWFyLCBpbnN0aXR1dGlvbmNvZGUpKQ0Kd3JpdGUuY3N2KGluc3RfYnlfeXIsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9pbnN0aXR1dGlvbmNvZGVfYnlfeXIuY3N2IikNCmluc3RfYnlfeXINCmBgYA0KDQptb250aA0KYGBge3J9DQppbnN0X2J5X210IDwtIHdpdGgocHJlc2VuY2UsIHRhYmxlKG1vbnRoLCBpbnN0aXR1dGlvbmNvZGUpKQ0Kd3JpdGUuY3N2KGluc3RfYnlfbXQsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9pbnN0aXR1dGlvbmNvZGVfYnlfbXRoLmNzdiIpDQppbnN0X2J5X210DQpgYGANCg0KIyMgZW52aXJvbm1lbnRhbCBjb3JyZWxhdGVzDQoNCjEpIEdldCB0aGUgbWF4LCBtaW4sIGFuIG1lYW4gdmFsdWVzIGFuZCBhZGQgaW50byBhIGRhdGFmcmFtZQ0KDQpUZW1wZXJhdHVyZQ0KYGBge3J9DQp0ZW1wX2RlcHRoX21heCA8LSBtYXgocHJlc2VuY2UkdGVtcF9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KdGVtcF9kZXB0aF9taW4gPC0gbWluKHByZXNlbmNlJHRlbXBfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnRlbXBfZGVwdGhfbWVhbiA8LSBtZWFuKHByZXNlbmNlJHRlbXBfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnRlbXBfc3VyZmFjZV9tYXggPC0gbWF4KHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KdGVtcF9zdXJmYWNlX21pbiA8LSBtaW4ocHJlc2VuY2UkdGVtcF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNClNhbGluaXR5DQpgYGB7cn0NCnNhbF9kZXB0aF9tYXggPC0gbWF4KHByZXNlbmNlJHNhbGluaXR5X2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpzYWxfZGVwdGhfbWluIDwtIG1pbihwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbmEucm0gPSBUUlVFKQ0Kc2FsX2RlcHRoX21lYW4gPC0gbWVhbihwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbmEucm0gPSBUUlVFKQ0Kc2FsX3N1cmZhY2VfbWF4IDwtIG1heChwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpzYWxfc3VyZmFjZV9taW4gPC0gbWluKHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21lYW4gPC0gbWVhbihwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KQ2hsDQpgYGB7cn0NCmNobF9kZXB0aF9tYXggPC0gbWF4KHByZXNlbmNlJGNobF9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KY2hsX2RlcHRoX21pbiA8LSBtaW4ocHJlc2VuY2UkY2hsX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpjaGxfZGVwdGhfbWVhbiA8LSBtZWFuKHByZXNlbmNlJGNobF9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWF4IDwtIG1heChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWluIDwtIG1pbihwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJGNobF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KTzINCmBgYHtyfQ0KbzJfZGVwdGhfbWF4IDwtIG1heChwcmVzZW5jZSRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfZGVwdGhfbWluIDwtIG1pbihwcmVzZW5jZSRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfZGVwdGhfbWVhbiA8LSBtZWFuKHByZXNlbmNlJG8yX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpvMl9zdXJmYWNlX21heCA8LSBtYXgocHJlc2VuY2UkbzJfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbzJfc3VyZmFjZV9taW4gPC0gbWluKHByZXNlbmNlJG8yX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCm8yX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJG8yX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCmBgYA0KDQpNTFANCmBgYHtyfQ0KbWxwX3N1cmZhY2VfbWF4IDwtIG1heChwcmVzZW5jZSRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbWxwX3N1cmZhY2VfbWluIDwtIG1pbihwcmVzZW5jZSRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbWxwX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJG1scF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KU1NIDQpgYGB7cn0NCnNzaF9zdXJmYWNlX21heCA8LSBtYXgocHJlc2VuY2Ukc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNzaF9zdXJmYWNlX21pbiA8LSBtaW4ocHJlc2VuY2Ukc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNzaF9zdXJmYWNlX21lYW4gPC0gbWVhbihwcmVzZW5jZSRzc2hfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNCmNyZWF0ZSBtYXRyaXgNCmBgYHtyfQ0KdGQgPC0gYyh0ZW1wX2RlcHRoX21heCwgdGVtcF9kZXB0aF9taW4sIHRlbXBfZGVwdGhfbWVhbikNCnRzIDwtIGModGVtcF9zdXJmYWNlX21heCwgdGVtcF9zdXJmYWNlX21pbiwgdGVtcF9zdXJmYWNlX21lYW4pDQpzZCA8LSBjKHNhbF9kZXB0aF9tYXgsIHNhbF9kZXB0aF9taW4sIHNhbF9kZXB0aF9tZWFuKQ0Kc3MgPC0gYyhzYWxfc3VyZmFjZV9tYXgsIHNhbF9zdXJmYWNlX21pbiwgc2FsX3N1cmZhY2VfbWVhbikNCmNkIDwtIGMoc2FsX2RlcHRoX21heCwgc2FsX2RlcHRoX21pbiwgc2FsX2RlcHRoX21lYW4pDQpjcyA8LSBjKHNhbF9zdXJmYWNlX21heCwgc2FsX3N1cmZhY2VfbWluLCBzYWxfc3VyZmFjZV9tZWFuKQ0Kb2QgPC0gYyhvMl9kZXB0aF9tYXgsIG8yX2RlcHRoX21pbiwgbzJfZGVwdGhfbWVhbikNCm9zIDwtIGMobzJfc3VyZmFjZV9tYXgsIG8yX3N1cmZhY2VfbWluLCBvMl9zdXJmYWNlX21lYW4pDQptbHAgPC0gYyhtbHBfc3VyZmFjZV9tYXgsIG1scF9zdXJmYWNlX21pbiwgbWxwX3N1cmZhY2VfbWVhbikNCnNzaCA8LSBjKHNzaF9zdXJmYWNlX21heCwgc3NoX3N1cmZhY2VfbWluLCBzc2hfc3VyZmFjZV9tZWFuKQ0KZW52X3N0YXRzIDwtIHJiaW5kKHRkLCB0cywgc2QsIHNzLCBjZCwgY3MsIG9kLCBvcywgbWxwLCBzc2gpDQpyb3cubmFtZXMoZW52X3N0YXRzKSA8LSBjKCJUZW1wIERlcHRoIiwgIlRlbXAgU3VyZmFjZSIsICJTYWxpbml0eSBEZXB0aCIsICJTYWxpbml0eSBTdXJmYWNlIiwgIkNobCBEZXB0aCIsICJDaGwgU3VyZmFjZSIsICJPeHlnZW4gRGVwdGgiLCAiT3h5Z2VuIFN1cmZhY2UiLCAiTUxQIiwgIlNTSCIpIA0KY29sbmFtZXMoZW52X3N0YXRzKSA8LSBjKCJNYXgiLCAiTWluIiwgIk1lYW4iKQ0Kd3JpdGUuY3N2KGVudl9zdGF0cywgIi4uL291dHB1dC9lbnYvZW52X2NvcnJlbGF0ZXNfYmFzaWNfc3RhdHMuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCmVudl9zdGF0cw0KYGBgDQoNCkhtbSBzb21lIHBvdGVudGlhbGx5IHN1c3BpY2lvdXMgdmFsdWVzIGhlcmUgaW4NCi0gT3h5Z2VuIERlcHRoIG1pbg0KLSBtbHAgIE1heA0KYW5kIG1heWJlIGFsc28NCi0gU2FsaW5pdHkgRGVwdGggbWluDQotIFNhbGluaXR5IFN1cmZhY2UgbWluDQotIENITCBkZXB0aCBtaW4NCi0gQ0hMIGRlcHRoIG1heA0KDQpsZXRzIGp1c3Qgc2VlIHdoZXJlIHRoZXNlIHZhbHVlcyBhcHBlYXIgYW5kIGNoZWNrIHRoZSBuZXRjZGYgbGF5ZXJzLiBOb3RlIEkgd2lsbCBjaGVjayB0aGVzZSB2YWx1ZXMgaW4gY3lnd2luIHVzaW5nIHRoZSBjZG8gb3BlcmF0b3IgaW5mb3Ygb24gdGhlIG5ldGNkZnMgKHRvIGVuc3VyZSB0aGVyZSB3YXMgbm8gaXNzdWUgd2l0aCBwcm9jZXNzaW5nIGluIFIpLiANCg0KDQpnZXQgdGhlIHllYXIgYW5kIG1vbnRoIHRoZXNlIHZhbHVlcyBhcHBlYXJlZCBpbg0KYGBge3J9DQpvMmRfY2hlY2tfeXIgPC0gc3Vic2V0KHByZXNlbmNlJHllYXIsIHByZXNlbmNlJG8yX2RlcHRoID09IG8yX2RlcHRoX21pbikNCm8yZF9jaGVja19tdGggPC0gc3Vic2V0KHByZXNlbmNlJG1vbnRoLCBwcmVzZW5jZSRvMl9kZXB0aCA9PSBvMl9kZXB0aF9taW4pDQpgYGANCk8yIGRlcHRoIG1pbiBpcyBpbiAyMDA1XzA4DQoNCkFuZCB2YWx1ZSBzZWVtcyBjb3JyZWN0DQoNCmBgYHtyfQ0KbWxwX2NoZWNrX3lyIDwtIHN1YnNldChwcmVzZW5jZSR5ZWFyLCBwcmVzZW5jZSRtbHBfc3VyZmFjZSA9PSBtbHBfc3VyZmFjZV9tYXgpDQptbHBfY2hlY2tfbXRoIDwtIHN1YnNldChwcmVzZW5jZSRtb250aCwgcHJlc2VuY2UkbWxwX3N1cmZhY2UgPT0gbWxwX3N1cmZhY2VfbWF4KQ0KYGBgDQptbHAgbWF4IGluIGluIDIwMDdfMTINCg0KQW5kIHllcyB0aGUgdmFsdWUgc2VlbXMgY29ycmVjdA0KDQpgYGB7cn0NCnNhbGRfY2hlY2tfeXIgPC0gc3Vic2V0KHByZXNlbmNlJHllYXIsIHByZXNlbmNlJHNhbGluaXR5X2RlcHRoID09IHNhbF9kZXB0aF9tYXgpDQpzYWxkX2NoZWNrX210aCA8LSBzdWJzZXQocHJlc2VuY2UkbW9udGgsIHByZXNlbmNlJHNhbGluaXR5X2RlcHRoID09IHNhbF9kZXB0aF9tYXgpDQpgYGANCnllYXIgbW9udGggMjAwMV8wNQ0KDQphbHNvIHNlZW1zIGNvcnJlY3QNCg0KYGBge3J9DQpzYWxzX2NoZWNrX3lyIDwtIHN1YnNldChwcmVzZW5jZSR5ZWFyLCBwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlID09IHNhbF9zdXJmYWNlX21pbikNCnNhbHNfY2hlY2tfbXRoIDwtIHN1YnNldChwcmVzZW5jZSRtb250aCwgcHJlc2VuY2Ukc2FsaW5pdHlfc3VyZmFjZSA9PSBzYWxfc3VyZmFjZV9taW4pDQpgYGANCnllYXIgbW9udGggMjE5OThfMDYNCg0Kb2sgYWdhaW4uLi4NCg0KTGVhdmUgdGhlIHJlc3QNCg0KDQojIyBzaW1wbGUgcGxvdHMgb2YgZW52LiBjb3JyZWxhdGVzDQoNCnRlbXBlcmF0dXJlDQpgYGB7cn0NCnBhcihtZnJvdz1jKDEsMikpDQpwbG90KHByZXNlbmNlJHRlbXBfZGVwdGgsIG1haW4gPSAiVGVtcCBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIktlbHZpbiIpDQpwbG90KHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbWFpbiA9ICJUZW1wIGF0IFN1cmZhY2UiLCB5bGFiID0gIktlbHZpbiIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wZXJhdHVyZV9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQpIbW0gbm90IG5lY2Vzc2FyaWx5IHZlcnkgaGVscGZ1bC4gQnV0IGFueXdheSwgbGV0cyBjYXJyeSBvbg0KDQpzYWxpbml0eQ0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKQ0KcGxvdChwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbWFpbiA9ICJTYWxpbml0eSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIlByYWN0aWNhbCBTYWxpbml0eSBVbml0cyIpDQpwbG90KHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UsIG1haW4gPSAiU2FsaW5pdHkgYXQgU3VyZmFjZSIsIHlsYWIgPSAiUHJhY3RpY2FsIFNhbGluaXR5IFVuaXRzIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc2FsaW5pdHlfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpDaGxvcm9waHlsbA0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKQ0KcGxvdChwcmVzZW5jZSRjaGxfZGVwdGgsIG1haW4gPSAiQ2hsIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbWFpbiA9ICJDaGwgYXQgU3VyZmFjZSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpPMg0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKQ0KcGxvdChwcmVzZW5jZSRvMl9kZXB0aCwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChwcmVzZW5jZSRvMl9zdXJmYWNlLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgU3VyZmFjZSIsIHlsYWIgPSAiTzIgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX3NpbXBsZXBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KbWxwDQpgYGB7cn0NCnBsb3QocHJlc2VuY2UkbWxwX3N1cmZhY2UsIG1haW4gPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIiwgeWxhYiA9ICJEZXB0aCAobSkiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpTU0gNCmBgYHtyfQ0KcGxvdChwcmVzZW5jZSRzc2hfc3VyZmFjZSwgbWFpbiA9ICJTZWEgU3VyZmFjZSBIZWlnaHQiLCB5bGFiID0gIkhlaWdodCAobSkiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpYWFggU0FNIC0gWU9VIFdBTlQgVE8gVEhJTksgQUJPVVQgRE9JTkcgVEhJUyBCWSBERVBUSCBSQVRIRVIgVEhBTiBBTEwgREVQVEhTKQ0KDQpgYGB7cn0NCnVuaXF1ZV9kZXB0aHMgPC0gdW5pcXVlKHByZXNlbmNlJGRlcHRobGF5ZXJubykNCnVuaXF1ZV9kZXB0aGRvcmRlcmVkIDwtIHNvcnQodW5pcXVlX2RlcHRocykgI2p1c3QgcHV0cyB0aGUgbGlzdCBpbiBvZGVyIHdpdGggbm8gTkENCmxlbmd0aCh1bmlxdWVfZGVwdGhkb3JkZXJlZCkNCmBgYA0Kb3VjaCAtIDM5IGxheWVycy4uLiBhIGpvYiBmb3IgYSBib3hwbG90IHByb2JhYmx5DQoNCmBgYHtyfQ0KDQpgYGANCg0KDQoNCiMgZnJlcXVlbmN5IHBsb3RzIG9mIGVudi4gY29ycg0KDQoNCnRlbXBlcmF0dXJlDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkdGVtcF9zdXJmYWNlLCBtYWluID0gIlRlbXAgYXQgU3VyZmFjZSIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSR0ZW1wX2RlcHQsIG1haW4gPSAiVGVtcCBhdCBEZXB0aCIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpjaGwNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbWFpbiA9ICJDaGxvcm9waHlsbCBhdCBTdXJmYWNlIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkY2hsX2RlcHRoLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9kZXB0aF9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0Kc2FsaW5pdHkNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlLCBtYWluID0gIlNhbGluaXR5IGF0IFN1cmZhY2UiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmhpc3QocHJlc2VuY2Ukc2FsaW5pdHlfZGVwdGgsIG1haW4gPSAiU2FsaW5pdHkgYXQgT2JzZXJ2YXRpb24gRGVwdGgiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9kZXB0aF9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0Kb3h5Z2VuDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkbzJfc3VyZmFjZSwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IFN1cmZhY2UiLCB4bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSRvMl9kZXB0aCwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9vMl9kZXB0aF9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KTUxQDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkbWxwLCBtYWluID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0Kc3NoDQpgYGB7cn0NCmhpc3QocHJlc2VuY2Ukc3NoLCBtYWluID0gIlNlYSBTdXJmYWNlIEhlaWdodCBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KDQojIyBzaW1wbGUgYm94cGxvdHMgb2YgZW52LiBjb3JyDQoNClNhbWUgYXMgYWJvdmUgYnV0IHdpdGggYm94cGxvdHMgKG1heSBwcm92aWRlIHNvbWUgbW9yZSB1c2VmdWwgaW5mbykNCg0KDQoNCmluZGl2aWR1YWwgcGxvdHMgb2YgZWFjaCB2YXJpYWJsZSANCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCmJveHBsb3QocHJlc2VuY2UkdGVtcF9kZXB0aCwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIktlbHZpbiIpDQpib3hwbG90KHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBTdXJmYWNlIiwgeWxhYiA9ICJLZWx2aW4iKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcF9ib3hwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpwYXIobWZyb3c9YygxLDIpKQ0KYm94cGxvdChwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbWFpbiA9ICJTYWxpbml0eSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIlBTVSIpDQpib3hwbG90KHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UsIG1haW4gPSAiU2FsaW5pdHkgYXQgU3VyZmFjZSIsIHlsYWIgPSAiUFNVIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JveHBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCnBhcihtZnJvdz1jKDEsMikpDQpib3hwbG90KHByZXNlbmNlJG8yX2RlcHRoLCBtYWluID0gIk8yIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAibW1vbC5tLTMiKQ0KYm94cGxvdChwcmVzZW5jZSRvMl9zdXJmYWNlLCBtYWluID0gIk8yIGF0IFN1cmZhY2UiLCB5bGFiID0gIm1tb2wubS0zIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2JveHBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCnBhcihtZnJvdz1jKDEsMikpDQpib3hwbG90KHByZXNlbmNlJGNobF9kZXB0aCwgbWFpbiA9ICJDaGxvcnBoeWxsIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAibW1vbC5tLTMiKQ0KYm94cGxvdChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbWFpbiA9ICJDaGxvcnBoeWxsIGF0IFN1cmZhY2UiLCB5bGFiID0gIm1tb2wubS0zIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9ib3hwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpwYXIobWZyb3c9YygxLDIpKQ0KYm94cGxvdChwcmVzZW5jZSRtbHBfc3VyZmFjZSwgbWFpbiA9ICJEZW5zaXR5IE1peGVkIExheWVyIFRoaWNrbmVzcyIsIHlsYWIgPSAibWV0ZXJzIikNCmJveHBsb3QocHJlc2VuY2Ukc3NoX3N1cmZhY2UsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IiwgeWxhYiA9ICJtZXRlcnMiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX3NzaF9ib3hwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSR0ZW1wX2RlcHRoIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiBEZXB0aCBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcGVyYXR1cmVfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRjaGxfZGVwdGggfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobG9yb3BoeWxsX2JveHBsb3RfZGVwdF9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2Ukc2FsaW5pdHlfZGVwdGggfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIERlcHRoIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9ib3hwbG90X2RlcHRfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJG8yX2RlcHRoIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIiwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIERlcHRoIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9vMl9ib3hwbG90X2RlcHRfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJG1scF9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyAobSkiLCBtYWluID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX2JveHBsb3RfZGVwdF9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2Ukc3NoX3N1cmZhY2UgfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IE9ic2VydmF0aW9uIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSR0ZW1wX2RlcHRoIH4gcHJlc2VuY2UkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJUZW1wZXJhdHVyZSAoS2VsdmluKSIsIG1haW4gPSAiVGVtcGVyYXR1cmUgYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcGVyYXR1cmVfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJGNobF9kZXB0aCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvY2hsX2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIERlcHRoIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRvMl9kZXB0aCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvb3h5Z2VuX2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRtbHAgfiBwcmVzZW5jZSR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyAobSkiLCBtYWluID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJHNzaCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IE9ic2VydmF0aW9uIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NzaF9ib3hwbG90X2RlcHRfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkdGVtcF9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiAoU3VyZmFjZSkgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkY2hsX3N1cmZhY2UgfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxvcm9waHlsbF9ib3hwbG90X3N1cmZhY2VfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UgfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIChTdXJmYWNlKSBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc2FsaW5pdHlfYm94cGxvdF9zdXJmYWNlX21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRvMl9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIiwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIChTdXJmYWNlKSBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfYm94cGxvdF9zdXJmYWNlX21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRtbHBfc3VyZmFjZSB+IHByZXNlbmNlJG1vbnRoLCB4bGFiID0gIm1vbnRoIiwgeWxhYiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgKG0pIiwgbWFpbiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgYXQgT2JzZXJ2YXRpb24gcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL21scF9ib3hwbG90X3N1cmZhY2VfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJHNzaF9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlNlYSBTdXJmYWNlIEhlaWdodCAobSkiLCBtYWluID0gIlNlYSBTdXJmYWNlIEhlaWdodCBhdCBPYnNlcnZhdGlvbiBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkdGVtcF9zdXJmYWNlIH4gcHJlc2VuY2UkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJUZW1wZXJhdHVyZSAoS2VsdmluKSIsIG1haW4gPSAiVGVtcGVyYXR1cmUgYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JveHBsb3Rfc3VyZmFjZV95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRjaGxfc3VyZmFjZSB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2Ukc2FsaW5pdHlfc3VyZmFjZSB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIChTdXJmYWNlKSBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkbzJfc3VyZmFjZSB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL294eWdlbl9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQoNCiMgYmFja2dyb3VuZCBwb2ludHMNClJlYWQgaW4gdGhlIHByZXNlbmNlIHBvaW50cw0KDQpgYGB7cn0NCmJhY2tncm91bmQgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vYmFja2dyb3VuZF9jb21wbGV0ZV9vYnNfY2Vsc19nbG9ib3QuY3N2IiwgaGVhZGVyID0gVFJVRSkNCmhlYWQoYmFja2dyb3VuZCkNCmBgYA0KDQojIGVudmlyb25tZW50YWwgY29ycmVsYXRlcw0KDQoxKSBHZXQgdGhlIG1heCwgbWluLCBhbiBtZWFuIHZhbHVlcyBhbmQgYWRkIGludG8gYSBkYXRhZnJhbWUNCg0KVGVtcGVyYXR1cmUNCmBgYHtyfQ0KdGVtcF9kZXB0aF9tYXhfYmFjayA8LSBtYXgoYmFja2dyb3VuZCR0ZW1wX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX2RlcHRoX21pbl9iYWNrIDwtIG1pbihiYWNrZ3JvdW5kJHRlbXBfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnRlbXBfZGVwdGhfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCR0ZW1wX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWF4X2JhY2sgPC0gbWF4KGJhY2tncm91bmQkdGVtcF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWluX2JhY2sgPC0gbWluKGJhY2tncm91bmQkdGVtcF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCR0ZW1wX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCmBgYA0KDQpTYWxpbml0eQ0KYGBge3J9DQpzYWxfZGVwdGhfbWF4X2JhY2sgPC0gbWF4KGJhY2tncm91bmQkc2FsaW5pdHlfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnNhbF9kZXB0aF9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRzYWxpbml0eV9kZXB0aCwgbmEucm0gPSBUUlVFKQ0Kc2FsX2RlcHRoX21lYW5fYmFjayA8LSBtZWFuKGJhY2tncm91bmQkc2FsaW5pdHlfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJHNhbGluaXR5X3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21pbl9iYWNrIDwtIG1pbihiYWNrZ3JvdW5kJHNhbGluaXR5X3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21lYW5fYmFjayA8LSBtZWFuKGJhY2tncm91bmQkc2FsaW5pdHlfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNCkNobA0KYGBge3J9DQpjaGxfZGVwdGhfbWF4X2JhY2sgPC0gbWF4KGJhY2tncm91bmQkY2hsX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpjaGxfZGVwdGhfbWluX2JhY2sgPC0gbWluKGJhY2tncm91bmQkY2hsX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpjaGxfZGVwdGhfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRjaGxfZGVwdGgsIG5hLnJtID0gVFJVRSkNCmNobF9zdXJmYWNlX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJGNobF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpjaGxfc3VyZmFjZV9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNCk8yDQpgYGB7cn0NCm8yX2RlcHRoX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJG8yX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpvMl9kZXB0aF9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfZGVwdGhfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfc3VyZmFjZV9tYXhfYmFjayA8LSBtYXgoYmFja2dyb3VuZCRvMl9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpvMl9zdXJmYWNlX21pbl9iYWNrIDwtIG1pbihiYWNrZ3JvdW5kJG8yX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCm8yX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRvMl9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KTUxQDQpgYGB7cn0NCm1scF9zdXJmYWNlX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJG1scF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQptbHBfc3VyZmFjZV9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbWxwX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNClNTSA0KYGBge3J9DQpzc2hfc3VyZmFjZV9tYXhfYmFjayA8LSBtYXgoYmFja2dyb3VuZCRzc2hfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0Kc3NoX3N1cmZhY2VfbWluX2JhY2sgPC0gbWluKGJhY2tncm91bmQkc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNzaF9zdXJmYWNlX21lYW5fYmFjayA8LSBtZWFuKGJhY2tncm91bmQkc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCmBgYA0KDQpjcmVhdGUgbWF0cml4DQpgYGB7cn0NCnRkYiA8LSBjKHRlbXBfZGVwdGhfbWF4X2JhY2ssIHRlbXBfZGVwdGhfbWluX2JhY2ssIHRlbXBfZGVwdGhfbWVhbl9iYWNrKQ0KdHNiIDwtIGModGVtcF9zdXJmYWNlX21heF9iYWNrLCB0ZW1wX3N1cmZhY2VfbWluX2JhY2ssIHRlbXBfc3VyZmFjZV9tZWFuX2JhY2spDQpzZGIgPC0gYyhzYWxfZGVwdGhfbWF4X2JhY2ssIHNhbF9kZXB0aF9taW5fYmFjaywgc2FsX2RlcHRoX21lYW5fYmFjaykNCnNzYiA8LSBjKHNhbF9zdXJmYWNlX21heF9iYWNrLCBzYWxfc3VyZmFjZV9taW5fYmFjaywgc2FsX3N1cmZhY2VfbWVhbl9iYWNrKQ0KY2RiIDwtIGMoc2FsX2RlcHRoX21heF9iYWNrLCBzYWxfZGVwdGhfbWluX2JhY2ssIHNhbF9kZXB0aF9tZWFuX2JhY2spDQpjc2IgPC0gYyhzYWxfc3VyZmFjZV9tYXhfYmFjaywgc2FsX3N1cmZhY2VfbWluX2JhY2ssIHNhbF9zdXJmYWNlX21lYW5fYmFjaykNCm9kYiA8LSBjKG8yX2RlcHRoX21heF9iYWNrLCBvMl9kZXB0aF9taW5fYmFjaywgbzJfZGVwdGhfbWVhbl9iYWNrKQ0Kb3NiIDwtIGMobzJfc3VyZmFjZV9tYXhfYmFjaywgbzJfc3VyZmFjZV9taW5fYmFjaywgbzJfc3VyZmFjZV9tZWFuX2JhY2spDQptbHBiIDwtIGMobWxwX3N1cmZhY2VfbWF4X2JhY2ssIG1scF9zdXJmYWNlX21pbl9iYWNrLCBtbHBfc3VyZmFjZV9tZWFuX2JhY2spDQpzc2hiIDwtIGMoc3NoX3N1cmZhY2VfbWF4X2JhY2ssIHNzaF9zdXJmYWNlX21pbl9iYWNrLCBzc2hfc3VyZmFjZV9tZWFuX2JhY2spDQplbnZfc3RhdHNfYmFjayA8LSByYmluZCh0ZGIsIHRzYiwgc2RiLCBzc2IsIGNkYiwgY3NiLCBvZGIsIG9zYiwgbWxwYiwgc3NoYikNCnJvdy5uYW1lcyhlbnZfc3RhdHNfYmFjaykgPC0gYygiVGVtcCBEZXB0aCIsICJUZW1wIFN1cmZhY2UiLCAiU2FsaW5pdHkgRGVwdGgiLCAiU2FsaW5pdHkgU3VyZmFjZSIsICJDaGwgRGVwdGgiLCAiQ2hsIFN1cmZhY2UiLCAiT3h5Z2VuIERlcHRoIiwgIk94eWdlbiBTdXJmYWNlIiwgIk1MUCIsICJTU0giKSANCmNvbG5hbWVzKGVudl9zdGF0c19iYWNrKSA8LSBjKCJNYXgiLCAiTWluIiwgIk1lYW4iKQ0Kd3JpdGUuY3N2KGVudl9zdGF0c19iYWNrLCAiLi4vb3V0cHV0L2Vudi9lbnZfY29ycmVsYXRlc19iYWNrZ3JvdW5kX2Jhc2ljX3N0YXRzLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQplbnZfc3RhdHNfYmFjaw0KYGBgDQoNCnRlbXBlcmF0dXJlDQpgYGB7cn0NCnBhcihtZnJvdz1jKDEsMikpDQpwbG90KGJhY2tncm91bmQkdGVtcF9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBUZW1wIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiS2VsdmluIikNCnBsb3QoYmFja2dyb3VuZCR0ZW1wX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgVGVtcCBhdCBTdXJmYWNlIiwgeWxhYiA9ICJLZWx2aW4iKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcGVyYXR1cmVfYmFja2dyb3VuZF9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCg0Kc2FsaW5pdHkNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCnBsb3QoYmFja2dyb3VuZCRzYWxpbml0eV9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBTYWxpbml0eSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIlByYWN0aWNhbCBTYWxpbml0eSBVbml0cyIpDQpwbG90KGJhY2tncm91bmQkc2FsaW5pdHlfc3VyZmFjZSwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBTYWxpbml0eSBhdCBTdXJmYWNlIiwgeWxhYiA9ICJQcmFjdGljYWwgU2FsaW5pdHkgVW5pdHMiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9iYWNrZ3JvdW5kX3NpbXBsZXBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KQ2hsb3JvcGh5bGwNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCnBsb3QoYmFja2dyb3VuZCRjaGxfZGVwdGgsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgQ2hsIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChiYWNrZ3JvdW5kJGNobF9zdXJmYWNlLCBtYWluID0gIkJhY2tncm91bmQgUG9pbnRzIENobCBhdCBTdXJmYWNlIiwgeWxhYiA9ICJDaGwgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX3NpbXBsZXBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KTzINCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCnBsb3QoYmFja2dyb3VuZCRvMl9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBEaXNzb2x2ZWQgT3h5Z2VuIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChiYWNrZ3JvdW5kJG8yX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgRGlzc29sdmVkIE94eWdlbiBhdCBTdXJmYWNlIiwgeWxhYiA9ICJPMiAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfYmFja2dyb3VuZF9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCm1scA0KYGBge3J9DQpwbG90KGJhY2tncm91bmQkbWxwX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIiwgeWxhYiA9ICJEZXB0aCAobSkiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYmFja2dyb3VuZF9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNClNTSA0KYGBge3J9DQpwbG90KGJhY2tncm91bmQkc3NoX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgU2VhIFN1cmZhY2UgSGVpZ2h0IiwgeWxhYiA9ICJIZWlnaHQgKG0pIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JhY2tncm91bmRfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQojIyBmcmVxdWVuY3kgcGxvdHMgb2YgZW52LiBjb3JyDQoNCg0KdGVtcGVyYXR1cmUNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJHRlbXBfc3VyZmFjZSwgbWFpbiA9ICJCYWNrZ3JvdW5kIFRlbXAgYXQgU3VyZmFjZSIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkdGVtcF9kZXB0LCBtYWluID0gIkJhY2tncm91bmQgVGVtcCBhdCBEZXB0aCIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfZGVwdGhfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmNobA0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkY2hsX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBDaGxvcm9waHlsbCBhdCBTdXJmYWNlIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJGNobF9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIENobG9yb3BoeWxsIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpzYWxpbml0eQ0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkc2FsaW5pdHlfc3VyZmFjZSwgbWFpbiA9ICJCYWNrZ3JvdW5kIFNhbGluaXR5IGF0IFN1cmZhY2UiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9iYWNrZ3JvdW5kX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJHNhbGluaXR5X2RlcHRoLCBtYWluID0gIkJhY2tncm91bmQgU2FsaW5pdHkgYXQgT2JzZXJ2YXRpb24gRGVwdGgiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9iYWNrZ3JvdW5kX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpveHlnZW4NCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJG8yX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBEaXNzb2x2ZWQgT3h5Z2VuIGF0IFN1cmZhY2UiLCB4bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2JhY2tncm91bmRfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkbzJfZGVwdGgsIG1haW4gPSAiQmFja2dyb3VuZCBEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9vMl9iYWNrZ3JvdW5kX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpNTFANCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJG1scCwgbWFpbiA9ICJCYWNrZ3JvdW5kIE1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYmFja2dyb3VuZF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpzc2gNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJHNzaCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFNlYSBTdXJmYWNlIEhlaWdodCBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfYmFja2dyb3VuZF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQojIyBzaW1wbGUgYm94cGxvdHMgb2YgZW52LiBjb3JyDQoNClNhbWUgYXMgYWJvdmUgYnV0IHdpdGggYm94cGxvdHMgKG1heSBwcm92aWRlIHNvbWUgbW9yZSB1c2VmdWwgaW5mbykNCg0KdGVtcGVyYXR1cmUNCg0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCR0ZW1wX2RlcHRoIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiVGVtcGVyYXR1cmUgKEtlbHZpbikiLCBtYWluID0gIlRlbXBlcmF0dXJlIGF0IEJhY2tncm91bmQgRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJGNobF9kZXB0aCB+IGJhY2tncm91bmQkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobG9yb3BoeWxsX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJHNhbGluaXR5X2RlcHRoIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJG8yX2RlcHRoIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgQmFja2dyb3VuZCBEZXB0aCBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfYmFja2dyb3VuZF9ib3hwbG90X2RlcHRfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkbWxwX3N1cmZhY2UgfiBiYWNrZ3JvdW5kJG1vbnRoLCB4bGFiID0gIm1vbnRoIiwgeWxhYiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgKG0pIiwgbWFpbiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgYXQgQmFja2dyb3VuZCBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJHNzaF9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IEJhY2tncm91bmQgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NzaF9iYWNrZ3JvdW5kX2JveHBsb3RfZGVwdF9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCR0ZW1wX2RlcHRoIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBCYWNrZ3JvdW5kIERlcHRoIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkY2hsX2RlcHRoIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvY2hsX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkc2FsaW5pdHlfZGVwdGggfiBiYWNrZ3JvdW5kJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc2FsaW5pdHlfYmFja2dyb3VuZF9ib3hwbG90X2RlcHRfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRvMl9kZXB0aCB+IGJhY2tncm91bmQkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIsIG1haW4gPSAiRGlzc29sdmVkIE94eWdlbiBhdCBCYWNrZ3JvdW5kIERlcHRoIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL294eWdlbl9iYWNrZ3JvdW5kX2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJG1scCB+IGJhY2tncm91bmQkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgKG0pIiwgbWFpbiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgYXQgQmFja2dyb3VuZCBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYmFja2dyb3VuZF9ib3hwbG90X2RlcHRfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRzc2ggfiBiYWNrZ3JvdW5kJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IEJhY2tncm91bmQgcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkdGVtcF9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiVGVtcGVyYXR1cmUgKEtlbHZpbikiLCBtYWluID0gIlRlbXBlcmF0dXJlIGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wZXJhdHVyZV9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRjaGxfc3VyZmFjZSB+IGJhY2tncm91bmQkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxvcm9waHlsbF9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRzYWxpbml0eV9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRvMl9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgQmFja2dyb3VuZCAoU3VyZmFjZSkgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2JhY2tncm91bmRfYm94cGxvdF9zdXJmYWNlX21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJG1scF9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIChtKSIsIG1haW4gPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIGF0IEJhY2tncm91bmQgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL21scF9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRzc2hfc3VyZmFjZSB+IGJhY2tncm91bmQkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlNlYSBTdXJmYWNlIEhlaWdodCAobSkiLCBtYWluID0gIlNlYSBTdXJmYWNlIEhlaWdodCBhdCBCYWNrZ3JvdW5kIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfYmFja2dyb3VuZF9ib3hwbG90X3N1cmZhY2VfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkdGVtcF9zdXJmYWNlIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBCYWNrZ3JvdW5kIChTdXJmYWNlKSBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wZXJhdHVyZV9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJGNobF9zdXJmYWNlIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJHNhbGluaXR5X3N1cmZhY2UgfiBiYWNrZ3JvdW5kJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JhY2tncm91bmRfYm94cGxvdF9zdXJmYWNlX3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkbzJfc3VyZmFjZSB+IGJhY2tncm91bmQkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIsIG1haW4gPSAiRGlzc29sdmVkIE94eWdlbiBhdCBCYWNrZ3JvdW5kIChTdXJmYWNlKSBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9veHlnZW5fYmFja2dyb3VuZF9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQojIyBjb3JyZWxhdGlvbnMgYmV0d2VlbiBiYWNrZ3JvdW5kIHBvaW50cw0KDQpjaGVjayB0byBzZWUgaWYgdGhlcmUgYXJlIGFueSBjb3JyZWxhdGlvbnMgaW4gdGhlIGVudi4gdmFyaWFibGVzIGZvciB0aGUgYmFja2dyb3VuZCBwb2ludHMNCg0KDQpmaXJzdCBzdWJzZXQgdGhlIGVudi5jb3JyZWxhdGUgY29sdW1ucyAoeW91IGRvbid0IG5lZWQgZXZlcnl0aGluZykNCg0KYGBge3J9DQpiYWNrZ3JvdW5kX2VudiA8LSBzdWJzZXQoYmFja2dyb3VuZCwgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgpKQ0KYmFja2dyb3VuZF9lbnZfY29yIDwtIGNvcihiYWNrZ3JvdW5kX2VudiwgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3YoYmFja2dyb3VuZF9lbnZfY29yLCAiLi4vb3V0cHV0L2Vudi9iYWNrZ3JvdW5kX2Vudl9jb3JyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQpiYWNrZ3JvdW5kX2NvcnJwbG90IDwtIGNvcnJwbG90KGJhY2tncm91bmRfZW52X2NvciAsIG1ldGhvZCA9ICJjb2xvciIsIHR5cGUgPSAidXBwZXIiLCBvcmRlciA9ICJhbHBoYWJldCIsIHRsLmNleCA9IDAuOCkgDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2JhY2tncm91bmRfZW52Y29yci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQp0byBnZXQgc29tZSBkZW5zaXR5IHBsb3RzIGFsbCBpbiBvbmUgZ3JhcGhpYywgeW91IG5lZWQgdG8gY2hhbmdlIGNodW5rIG91dHB1dCB0byBpbiBjb25zb2xlLCB0aGVuIGdvIHRvIHRoZSBwbG90IHRhYiwgbWFrZSBpdCBmaWxsIHRoZSBzY3JlZW4sIHRoZW4gcnVuIHRoZW4gbWFrZSBiaWdnZXIgdGhlbiBzYXZlIDooIChwcm9iYWJseSBhIGJldHRlciB3YXkgLSB0aGlzIHNlZW1zIHRvIGJlIGFuIGlzc3VlIHdpdGggUlN0dWRpbykNCmBgYHtyfQ0KcGFyKG1mcm93PWMoNCw0KSkNCmZvcihpIGluIDE6MTYpew0KICBwbG90KGRlbnNpdHkoYmFja2dyb3VuZF9lbnZbLGldLCBuYS5ybT1UKSwgbWFpbiA9IG5hbWVzKGJhY2tncm91bmRfZW52KVtpXSkNCn0NCmBgYA0KUFVUIFRIRSBDSFVOSyBPVVRQVVQgQkFDSyBUTyBJTkxJTkUNCg0KDQphZGQgbmFmbyByZWdpb24gYW5kIGdlYXIgdHlwZSBpbnRvIHRoZSBtaXgNCg0KDQpmaXJzdCBzdWJzZXQgdGhlIGVudi5jb3JyZWxhdGUgY29sdW1ucyArIGJvdHRvbV9kZXB0aCAoeW91IGRvbid0IG5lZWQgZXZlcnl0aGluZykNCg0KYGBge3J9DQpiYWNrZ3JvdW5kX2VudmJvdGRlcHRoIDwtIHN1YnNldChiYWNrZ3JvdW5kLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCwgYm90dG9tX2RlcHRoKSkNCmJhY2tncm91bmRfZW52Ym90ZGVwdGhfY29yIDwtIGNvcihiYWNrZ3JvdW5kX2VudmJvdGRlcHRoLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihiYWNrZ3JvdW5kX2VudmJvdGRlcHRoX2NvciwgIi4uL291dHB1dC9lbnYvYmFja2dyb3VuZF9lbnZib3RkZXB0aF9jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCmJhY2tncm91bmRfY29ycnBsb3QgPC0gY29ycnBsb3QoYmFja2dyb3VuZF9lbnZib3RkZXB0aF9jb3IgLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgb3JkZXIgPSAiYWxwaGFiZXQiLCB0bC5jZXggPSAwLjgpIA0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9iYWNrZ3JvdW5kX2VudmJvdGRlcHRoX2Nvci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQoNCiMjIGNvcnJlbGF0aW9ucyBiZXR3ZWVuIHByZXNlbmNlIHBvaW50cw0KDQpjaGVjayB0byBzZWUgaWYgdGhlcmUgYXJlIGFueSBjb3JyZWxhdGlvbnMgaW4gdGhlIGVudi4gdmFyaWFibGVzDQoNCmZpcnN0IHN1YnNldCB0aGUgZW52LmNvcnJlbGF0ZSBjb2x1bW5zICh5b3UgZG9uJ3QgbmVlZCBldmVyeXRoaW5nKSB0aGVuIHVzZSBjb3IgdG8gZ2V0IHRoZSBjb3JyZWxhdGlvbiB2YWx1ZXMsIGFuZCB0aGVuIGNvcnJwbG90IGZvciBhIHZpc3VhbA0KDQpgYGB7cn0NCnByZXNfZW52IDwtIHN1YnNldChwcmVzZW5jZSwgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgsIGJvdHRvbV9kZXB0aCkpDQpwcmVzX2Vudl9jb3IgPC0gY29yKHByZXNfZW52LCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihwcmVzX2Vudl9jb3IsICIuLi9vdXRwdXQvZW52L3ByZXNfZW52X2NvcnIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnByZXNfY29ycnBsb3QgPC0gY29ycnBsb3QocHJlc19lbnZfY29yICwgbWV0aG9kID0gImNvbG9yIiwgdHlwZSA9ICJ1cHBlciIsIG9yZGVyID0gImFscGhhYmV0IiwgdGwuY2V4ID0gMC44KSANCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvcHJlc19lbnZjb3JyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCnRvIGdldCBzb21lIGRlbnNpdHkgcGxvdHMgYWxsIGluIG9uZSBncmFwaGljLCB5b3UgbmVlZCB0byBjaGFuZ2UgY2h1bmsgb3V0cHV0IHRvIGluIGNvbnNvbGUsIHRoZW4gZ28gdG8gdGhlIHBsb3QgdGFiLCBtYWtlIGl0IGZpbGwgdGhlIHNjcmVlbiwgdGhlbiBydW4gdGhlbiBtYWtlIGJpZ2dlciB0aGVuIHNhdmUgOiggKHByb2JhYmx5IGEgYmV0dGVyIHdheSAtIHRoaXMgc2VlbXMgdG8gYmUgYW4gaXNzdWUgd2l0aCBSU3R1ZGlvKQ0KYGBge3J9DQpwYXIobWZyb3c9Yyg0LDQpKQ0KZm9yKGkgaW4gMToxNil7DQogIHBsb3QoZGVuc2l0eShwcmVzX2VudlssaV0sIG5hLnJtPVQpLCBtYWluID0gbmFtZXMocHJlc19lbnYpW2ldKQ0KfQ0KYGBgDQpQVVQgVEhFIENIVU5LIE9VVFBVVCBCQUNLIFRPIElOTElORQ0KDQoNCiMjIGRlbnNpdHkgcGxvdCB3aXRoIGJhY2tncm91bmQgYW5kIHByZXNlbmNlIGVudi4gZGF0YQ0KDQpJbnNwaXJlZCBieSBNZXJyb3cgMjAxMyAtIHRvcCBwYXJhZ3JhcGggb2YgcGFnZSAxMDYzIChhcmUgdGhlIHNwZWNpZXMgb2JzZXJ2YXRpb25zIHVuaWZvcm1seSBkaXN0cmlidXRlZCBvdmVyIHRoZSBiYWNrZ3JvdW5kLCBvciBhcmUgdGhleSBza2V3ZWQpDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IHRlbXBfZGVwdGgpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcF9kZXB0aF9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IHRlbXBfc3VyZmFjZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wX3N1cmZhY2VfYmFja3ZzcHJlcy5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChwcmVzX2VudiwgYWVzKHggPSBjaGxfc3VyZmFjZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxfc3VyZmFjZV9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IGNobF9kZXB0aCkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxfZGVwdGhfYmFja3ZzcHJlcy5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChwcmVzX2VudiwgYWVzKHggPSBzYWxpbml0eV9zdXJmYWNlKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFLCBjb2xvdXIgPSAicmVkIikgKyBnZW9tX2RlbnNpdHkoZGF0YT1iYWNrZ3JvdW5kX2VudiwgbmEucm0gPSBUUlVFLCBjb2xvdXIgPSAiYmx1ZSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X3N1cmZhY2VfYmFja3ZzcHJlcy5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChwcmVzX2VudiwgYWVzKHggPSBzYWxpbml0eV9kZXB0aCkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9kZXB0aF9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IG8yX3N1cmZhY2UpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfc3VyZmFjZV9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IG8yX2RlcHRoKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFLCBjb2xvdXIgPSAicmVkIikgKyBnZW9tX2RlbnNpdHkoZGF0YT1iYWNrZ3JvdW5kX2VudiwgbmEucm0gPSBUUlVFLCBjb2xvdXIgPSAiYmx1ZSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2RlcHRoX2JhY2t2c3ByZXMucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QocHJlc19lbnYsIGFlcyh4ID0gbWxwX3N1cmZhY2UpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX2JhY2t2c3ByZXMucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QocHJlc19lbnYsIGFlcyh4ID0gc3NoX3N1cmZhY2UpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JhY2t2c3ByZXMucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KDQojIE5BRk8gUmVnaW9ucw0KDQpjb21wYXJlIHRoZSBlbnZpcm9ubWVudGFsIGNvcnJlbGF0ZXMgYmV0d2VlbiBkaWZmZXJlbnQgTkFGTyByZWdpb25zDQoNCmZpcnN0IHNlZSB3aGljaCBuYWZvIHpvbmVzIHdlcmUgc2FtcGxlZCBpbiBlYWNoIHllYXINCmBgYHtyIHByZXNlbmNlIG5hZm8gYnkgeWVhcn0NCm5hZm9fYnlfeXIgPC0gd2l0aChwcmVzZW5jZSwgdGFibGUoeWVhciwgbmFmb196b25lKSkNCndyaXRlLmNzdihuYWZvX2J5X3lyLCBmaWxlID0gIi4uL291dHB1dC9iaW8vbmFmb3pvbmVfYnlfeXIuY3N2IikNCm5hZm9fYnlfeXINCmBgYA0KDQphbmQgYnkgbW9udGgNCmBgYHtyIHByc2VuY2UgbmFmbyBieSBtb250aH0NCm5hZm9fYnlfbXRoIDwtIHdpdGgocHJlc2VuY2UsIHRhYmxlKG5hZm9fem9uZSwgbW9udGgpKQ0Kd3JpdGUuY3N2KG5hZm9fYnlfbXRoLCBmaWxlID0gIi4uL291dHB1dC9iaW8vbmFmb3pvbmVfYnlfbXRoLmNzdiIpDQpuYWZvX2J5X210aA0KYGBgDQoNCkludGVyZXN0aW5nIHRoYXQgdGhlcmUgaXMgYSBwb2ludCBpbiAxQyAtIHRoaXMgaXMgb3V0c2lkZSBDYW5hZGlhbiB3YXRlcnMuLi4uIGFueXdheQ0KYGBge3J9DQpvbmVjIDwtICBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiMUMiKQ0Kb25lYw0KYGBgDQoNCiMjIGRlbnNpdHkgcGxvdCB3aXRoIGJhY2tncm91bmQgYW5kIHByZXNlbmNlIGVudi4gZGF0YSBieSBOQUZPIHJlZ2lvbg0KDQpXaGF0IEkgd2FudCB0byBzZWUgaWYgaWYgdGhlcmUgaXMgYSBtYXJrZWQgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBlbnYuIGNvcnJlbGF0ZXMgb2YgdGhlIHByZXNlbmNlIHBvaW50cyBiZXR3ZWVuIE5BRk8gcmVnaW9ucy4gVGhpcyBpcyBhbHNvIHRvIHRyeSBkZWFsIHdpdGggc2FtcGxpbmcgYmlhcyAoYi9jIHRoZSB3aG9sZSByZWdpb24gaXMgbm90IHVuaWZvcm1seSBzYW1wbGVkIGluIGVhY2ggbW9udGgsIGJ1dCByYXRoZXIgbmFmbyByZWdpb25zIGhhdmUgYSBzdHJvbmcgbW9udGggYmlhcykNCg0KZmlyc3QgY3JlYXRlIE5BRk8tcmVnaW9uIGRhdGFzZXRzDQoNCmBgYHtyIHByZXNlbmNlIGJ5IG5hZm99DQpuYWZvMGEgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjBBIikNCm5hZm8wYiA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiMEIiKQ0KbmFmbzFjIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIxQyIpDQpuYWZvMmcgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjJHIikNCm5hZm8yaCA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiMkgiKQ0KbmFmbzJqIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIySiIpDQpuYWZvM2sgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjNLIikNCm5hZm8zbCA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiM0wiKQ0KbmFmbzNtIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIzTSIpDQpuYWZvM24gPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjNOIikNCm5hZm8zbyA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiM08iKQ0KbmFmbzNwcyA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiM1BzIikNCm5hZm80ciA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiNFIiKQ0KbmFmbzRzIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICI0UyIpDQpuYWZvNHQgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjRUIikNCm5hZm80dm4gPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjRWbiIpDQpuYWZvNHZzIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICI0VnMiKQ0KbmFmbzR3IDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICI0VyIpDQpuYWZvNHggPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjRYIikNCm5hZm81eSA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiNVkiKQ0KbmFmbzV6ZSA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiNVpFIikNCm5hZm9odWRzb24gPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIkh1ZHNvblN0cmFpdCIpDQpgYGANCg0KcGxvdCBieSBlYWNoIHZhcmlhYmxlLCBsZXNzIDNtICgyIHNhbXBsZXMpIDFjIChvbmUgc2FtcGxlKSBhbmQgNXplICh6ZXJvIHNhbXBsZXM/ISkNCmBgYHtyIHByZXNlbmNlIGJ5IG5hZm8gYnkgdmFyaWFibGV9DQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IHRlbXBfc3VyZmFjZSwgY29sb3VyID0gbmFmb196b25lKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8wYiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yZywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zaywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zcHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80eCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm81eSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm9odWRzb24sIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfbmFmb19wbG90cy90ZW1wX3N1cmZhY2VfbmFmby5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KG5hZm8wYSwgYWVzKHggPSB0ZW1wX2RlcHRoLCBjb2xvdXIgPSBuYWZvX3pvbmUpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzBiLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJnLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJoLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJqLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNrLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNsLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNvLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNwcywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80ciwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dm4sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR3LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR4LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzV5LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmb2h1ZHNvbiwgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9uYWZvX3Bsb3RzL3RlbXBfZGVwdGhfbmFmby5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KG5hZm8wYSwgYWVzKHggPSBjaGxfc3VyZmFjZSwgY29sb3VyID0gbmFmb196b25lKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8wYiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yZywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zaywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zcHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80eCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm81eSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm9odWRzb24sIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfbmFmb19wbG90cy9jaGxfc3VyZmFjZV9uYWZvLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IGNobF9kZXB0aCwgY29sb3VyID0gbmFmb196b25lKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8wYiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yZywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zaywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zcHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80eCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm81eSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm9odWRzb24sIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfbmFmb19wbG90cy9jaGxfZGVwdGhfbmFmby5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KG5hZm8wYSwgYWVzKHggPSBzYWxpbml0eV9zdXJmYWNlLCBjb2xvdXIgPSBuYWZvX3pvbmUpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzBiLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJnLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJoLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJqLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNrLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNsLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNvLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNwcywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80ciwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dm4sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR3LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR4LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzV5LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmb2h1ZHNvbiwgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9uYWZvX3Bsb3RzL3NhbGluaXR5X3N1cmZhY2VfbmFmby5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KG5hZm8wYSwgYWVzKHggPSBzYWxpbml0eV9kZXB0aCwgY29sb3VyID0gbmFmb196b25lKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8wYiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yZywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zaywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zcHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80eCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm81eSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm9odWRzb24sIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfbmFmb19wbG90cy9zYWxpbml0eV9kZXB0aF9uYWZvLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IG8yX3N1cmZhY2UsIGNvbG91ciA9IG5hZm9fem9uZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMGIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmosIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2ssIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2wsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM28sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM3BzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRyLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dnMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNXksIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvaHVkc29uLCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X25hZm9fcGxvdHMvbzJfc3VyZmFjZV9uYWZvLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IG8yX2RlcHRoLCBjb2xvdXIgPSBuYWZvX3pvbmUpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzBiLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJnLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJoLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJqLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNrLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNsLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNvLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNwcywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80ciwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dm4sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR3LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR4LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzV5LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmb2h1ZHNvbiwgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9uYWZvX3Bsb3RzL28yX2RlcHRoX25hZm8ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChuYWZvMGEsIGFlcyh4ID0gbWxwX3N1cmZhY2UsIGNvbG91ciA9IG5hZm9fem9uZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMGIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmosIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2ssIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2wsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM28sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM3BzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRyLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dnMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNXksIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvaHVkc29uLCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X25hZm9fcGxvdHMvbWxwX25hZm8ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChuYWZvMGEsIGFlcyh4ID0gc3NoX3N1cmZhY2UsIGNvbG91ciA9IG5hZm9fem9uZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMGIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmosIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2ssIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2wsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM28sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM3BzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRyLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dnMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNXksIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvaHVkc29uLCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X25hZm9fcGxvdHMvc3NoX25hZm8ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KDQoNCkxldCdzIHBsb3QgdGhlIHZhcmlhYmxlcyBieSBuYWZvIHJlZ2lvbi95ZWFyIHRoZW4gYnkgbW9udGgNCg0KDQpgYGB7cn0NCnByOTggPC0gc3Vic2V0KHByZXNlbmNlLCB5ZWFyID09ICIxOTk4IikNCmJveHBsb3QocHI5OCR0ZW1wX2RlcHRoIH4gcHI5OCRuYWZvX3pvbmUsIHhsYWIgPSAiTkFGTyBSZWdpb24iLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiBEZXB0aCBwZXIgTkFGTyBab25lIikNCmBgYA0KDQpgYGB7cn0NCnByOTggPC0gc3Vic2V0KHByZXNlbmNlLCB5ZWFyID09ICIxOTk4IikNCnByMTEgPC0gc3Vic2V0KHByZXNlbmNlLCB5ZWFyID09ICIyMDExIikNCnBhcihtZnJvdz1jKDIsMSkpDQpib3hwbG90KHByOTgkdGVtcF9kZXB0aCB+IHByOTgkbmFmb196b25lLCB4bGFiID0gIk5BRk8gUmVnaW9uIiwgeWxhYiA9ICJUZW1wZXJhdHVyZSAoS2VsdmluKSIsIG1haW4gPSAiVGVtcGVyYXR1cmUgYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIE5BRk8gWm9uZSIpDQpib3hwbG90KHByMTEkdGVtcF9kZXB0aCB+IHByMTEkbmFmb196b25lLCB4bGFiID0gIk5BRk8gUmVnaW9uIiwgeWxhYiA9ICJUZW1wZXJhdHVyZSAoS2VsdmluKSIsIG1haW4gPSAiVGVtcGVyYXR1cmUgYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIE5BRk8gWm9uZSIpDQpgYGANCg0Kb2sgc2NyYXAgdGhlIG5hZm8gcmVnaW9uIGFuYWx5c2lzIC0gaXQgaXMgdG9vIG1peGVkIHVwIHdpdGggbW9udGggKHNvIHNlZWluZyBpZiByZWdpb24gb3IgbW9udGggaXMgYSBmYWN0b3IgdGhhdCBuZWVkcyB0byBiZSBmYWN0b3JlZCBpbiB0byB0aGUgbW9kZWwgaXMgbm90IGFwcHJvcHJpYXRlKQ0KDQojIHJlbWFwIHdobyBzYW1wbGVkDQoNCk5vdyBsZXRzIGNoZWNrIHRoZSBudW1iZXIgb2YgcmVjb3JkcyBhbmQgc3BhdGlhbC10ZW1wb3JhbCBkaXN0cmlidXRpb24gb2YgdGhlIG9ic2VydmF0aW9ucyBieSBpbnN0aXR1dGlvbiBjb2RlIHRvIG1ha2Ugc3VyZSBub25lIGFyZSBkb2RneQ0KDQpmaXJzdCBhIHRhYmxlIG9mIGhvdyBtYW55IG9ic2VydmF0aW9ucyBlYWNoIGluc3RpdHVpb25jb2RlIGhhcw0KYGBge3IgaW5zdGl0dXRpb24gY29kZSBhbmFseXNpcyAtIGNvdW50fQ0Kb2JzX2J5X2lucyA8LSBjb3VudChwcmVzZW5jZSwgImluc3RpdHV0aW9uY29kZSIpDQpvYnNfYnlfaW5zDQp3cml0ZS5jc3Yob2JzX2J5X2lucywgZmlsZSA9ICIuLi9vdXRwdXQvYmlvL3NhbXBsaW5naW5zdGl0dXRpb25zL25vX29ic2VydmF0aW9uc19pbnN0aXR1dGlvbmNvZGUuY3N2IikNCmBgYA0Kb2sgc28gSU1SLCBOQUZPLCBJQ0VTLCAmIFVTTSBoYXZlIHZlcnkgZmV3IGVudHJpZXMgKDEsIDEsIDEsIGFuZCAzIHJlc3BlY3RpdmVseSkNCg0KTGV0cyB0YWtlIGEgbG9vayBhdCB0aGUgc3BhdGlhbCBicmVha2Rvd24gb2YgdGhlc2UgaW5zdGl0dXRpb25zLkZpcnN0IGFsbCBwb2ludHMuLi4NCg0KYGBge3J9DQptYXAyIDwtIGdldE1hcChyZXNvbHV0aW9uID0gImxvdyIpICNjcmVhdGVzIGFuIG9iamVjdCBjYWxsZWQgbWFwIGF0IGxvdyByZXNvdWx0aW9uDQpwbG90KG1hcDIsIHhsaW0gPSBjKC03MCwgLTQzKSwgeWxpbSA9YygzOCwgNzApLCBhc3AgPSAxLCBtYWluID0gIkFsbCBPY2N1cnJlbmNlcyIsIGNvbCA9ICJjb3Juc2lsayIpICN0aGUgeCBhbmQgeSBsaW0gYXJlIHRoZSBsb25nLWxhdCBib3VuZHMgb2YgdGhlIG1hcA0KcG9pbnRzKHByZXNlbmNlJGRlY2ltYWxMb25naXR1ZGUsIHByZXNlbmNlJGRlY2ltYWxMYXRpdHVkZSwgY29sID0gInJlZCIpICN0aGlzIGFkZHMgcG9pbnRzIHRvIHRoZSBtYXBldCIsIHhsYWIgPSAiTG9uZ2l0dWRlIiwgeWxhYiA9ICJMYXRpdHVkZSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvYmlvL3NhbXBsaW5naW5zdGl0dXRpb25zL2FsbF9vY2N1cnJlbmNlcy5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCmBgYA0KTm90ZSB0aGVyZSBpcyBvbmUgcG9pbnQgdXAgYnkgaWNlbGFuZCB0aGF0IHlvdSBzaG91bGQgZ2V0IHJpZCBvZiAoSWNlbGFuZGljIHBvcHVsYXRpb24gdGhvdWdodCB0byBiZSBzZXBlcmF0ZSBmcm9tIExhYnJhZG9yLCBidXQgaXQgaXMgdW5jbGVhciBpZiB0aGlzIGlzIHRydWUgb3Igbm90KS4NCg0KTWFwIHRoZSBpbnN0aXR1dGlvbmNvZGUgPT0gQVJDIG9ubHkgZGF0YS4uLg0KYGBge3IgbWFwIG9icyBieSBpbnN0aXR1dHVpb259DQpBUkNfb2JzIDwtIHByZXNlbmNlW3ByZXNlbmNlJGluc3RpdHV0aW9uY29kZSA9PSAiQVJDIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJBcmMgT2NjdXJyZW5jZXMiLCBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhBUkNfb2JzJGRlY2ltYWxMb25naXR1ZGUsIEFSQ19vYnMkZGVjaW1hbExhdGl0dWRlLCBjb2wgPSAicmVkIikgI3RoaXMgYWRkcyBwb2ludHMgdG8gdGhlIG1hcGV0IiwgeGxhYiA9ICJMb25naXR1ZGUiLCB5bGFiID0gIkxhdGl0dWRlIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9iaW8vc2FtcGxpbmdpbnN0aXR1dGlvbnMvQVJDX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KREZPQ0VOQVJDX29icyA8LSBwcmVzZW5jZVtwcmVzZW5jZSRpbnN0aXR1dGlvbmNvZGUgPT0gIkRGT0NFTkFSQyIsIF0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM5LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiREZPIENlbnRyYWwgJiBBcmN0aWMgT2NjdXJyZW5jZXMiLCAgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMoREZPQ0VOQVJDX29icyRkZWNpbWFsTG9uZ2l0dWRlLCBERk9DRU5BUkNfb2JzJGRlY2ltYWxMYXRpdHVkZSwgY29sID0gInJlZCIpICN0aGlzIGFkZHMgcG9pbnRzIHRvIHRoZSBtYXBldCIsIHhsYWIgPSAiTG9uZ2l0dWRlIiwgeWxhYiA9ICJMYXRpdHVkZSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvYmlvL3NhbXBsaW5naW5zdGl0dXRpb25zL0RGT0NFTkFSQ19vY2N1cnJlbmNlc19hbGwucG5nIikgI3RoaXMgcHJpbnRzIGEgcG5nIG9mIHRoZSBwbG90DQpkZXYub2ZmKCkgI3RoaXMgdHVybnMgb2ZmIHRoZSBwcmludCBjb21tYW5kDQoNCkRGT0d1bGZfb2JzIDwtIHByZXNlbmNlW3ByZXNlbmNlJGluc3RpdHV0aW9uY29kZSA9PSAiREZPR3VsZiIsIF0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM5LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiREZPIEd1bGYgT2NjdXJyZW5jZXMiLCAgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMoREZPR3VsZl9vYnMkZGVjaW1hbExvbmdpdHVkZSwgREZPR3VsZl9vYnMkZGVjaW1hbExhdGl0dWRlLCBjb2wgPSAicmVkIikgI3RoaXMgYWRkcyBwb2ludHMgdG8gdGhlIG1hcGV0IiwgeGxhYiA9ICJMb25naXR1ZGUiLCB5bGFiID0gIkxhdGl0dWRlIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9iaW8vc2FtcGxpbmdpbnN0aXR1dGlvbnMvREZPR3VsZl9vY2N1cnJlbmNlc19hbGwucG5nIikgI3RoaXMgcHJpbnRzIGEgcG5nIG9mIHRoZSBwbG90DQpkZXYub2ZmKCkgI3RoaXMgdHVybnMgb2ZmIHRoZSBwcmludCBjb21tYW5kDQoNCkRGT0lTRE1fb2JzIDwtIHByZXNlbmNlW3ByZXNlbmNlJGluc3RpdHV0aW9uY29kZSA9PSAiREZPSVNETSIsIF0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM5LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiREZPIElTRE0gT2NjdXJyZW5jZXMiLCAgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMoREZPSVNETV9vYnMkZGVjaW1hbExvbmdpdHVkZSwgREZPSVNETV9vYnMkZGVjaW1hbExhdGl0dWRlLCBjb2wgPSAicmVkIikgI3RoaXMgYWRkcyBwb2ludHMgdG8gdGhlIG1hcGV0IiwgeGxhYiA9ICJMb25naXR1ZGUiLCB5bGFiID0gIkxhdGl0dWRlIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9iaW8vc2FtcGxpbmdpbnN0aXR1dGlvbnMvREZPSVNETV9vY2N1cnJlbmNlc19hbGwucG5nIikgI3RoaXMgcHJpbnRzIGEgcG5nIG9mIHRoZSBwbG90DQpkZXYub2ZmKCkgI3RoaXMgdHVybnMgb2ZmIHRoZSBwcmludCBjb21tYW5kDQoNCkRGT01UTVNfb2JzIDwtIHByZXNlbmNlW3ByZXNlbmNlJGluc3RpdHV0aW9uY29kZSA9PSAiREZPTVRNUyIsIF0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM5LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiREZPIE1hcml0aW1lcyBPY2N1cnJlbmNlcyIsICBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhERk9NVE1TX29icyRkZWNpbWFsTG9uZ2l0dWRlLCBERk9NVE1TX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9ERk9NVE1TX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KREZPTkxfb2JzIDwtIHByZXNlbmNlW3ByZXNlbmNlJGluc3RpdHV0aW9uY29kZSA9PSAiREZPTkwiLCBdDQptYXAyIDwtIGdldE1hcChyZXNvbHV0aW9uID0gImxvdyIpICNjcmVhdGVzIGFuIG9iamVjdCBjYWxsZWQgbWFwIGF0IGxvdyByZXNvdWx0aW9uDQpwbG90KG1hcDIsIHhsaW0gPSBjKC03MCwgLTQzKSwgeWxpbSA9YygzOSwgNzApLCBhc3AgPSAxLCBtYWluID0gIkRGTyBOZXdmb3V1bmRsYW5kICYgTGFicmFkb3IgT2NjdXJyZW5jZXMiLCAgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMoREZPTkxfb2JzJGRlY2ltYWxMb25naXR1ZGUsIERGT05MX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9ERk9OTF9vY2N1cnJlbmNlc19hbGwucG5nIikgI3RoaXMgcHJpbnRzIGEgcG5nIG9mIHRoZSBwbG90DQpkZXYub2ZmKCkgI3RoaXMgdHVybnMgb2ZmIHRoZSBwcmludCBjb21tYW5kDQoNCkRGT1FDX29icyA8LSBwcmVzZW5jZVtwcmVzZW5jZSRpbnN0aXR1dGlvbmNvZGUgPT0gIkRGT1FDIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJERk8gUXVlYmVjIE9jY3VycmVuY2VzIiwgIGNvbCA9ICJjb3Juc2lsayIpICN0aGUgeCBhbmQgeSBsaW0gYXJlIHRoZSBsb25nLWxhdCBib3VuZHMgb2YgdGhlIG1hcA0KcG9pbnRzKERGT1FDX29icyRkZWNpbWFsTG9uZ2l0dWRlLCBERk9RQ19vYnMkZGVjaW1hbExhdGl0dWRlLCBjb2wgPSAicmVkIikgI3RoaXMgYWRkcyBwb2ludHMgdG8gdGhlIG1hcGV0IiwgeGxhYiA9ICJMb25naXR1ZGUiLCB5bGFiID0gIkxhdGl0dWRlIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9iaW8vc2FtcGxpbmdpbnN0aXR1dGlvbnMvREZPUUNfb2NjdXJyZW5jZXNfYWxsLnBuZyIpICN0aGlzIHByaW50cyBhIHBuZyBvZiB0aGUgcGxvdA0KZGV2Lm9mZigpICN0aGlzIHR1cm5zIG9mZiB0aGUgcHJpbnQgY29tbWFuZA0KDQpNYWluZURNUl9vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJNYWluZURNUiIsIF0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM5LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiTWFpbmUgRE1SIE9jY3VycmVuY2VzIiwgIGNvbCA9ICJjb3Juc2lsayIpICN0aGUgeCBhbmQgeSBsaW0gYXJlIHRoZSBsb25nLWxhdCBib3VuZHMgb2YgdGhlIG1hcA0KcG9pbnRzKE1haW5lRE1SX29icyRkZWNpbWFsTG9uZ2l0dWRlLCBNYWluZURNUl9vYnMkZGVjaW1hbExhdGl0dWRlLCBjb2wgPSAicmVkIikgI3RoaXMgYWRkcyBwb2ludHMgdG8gdGhlIG1hcGV0IiwgeGxhYiA9ICJMb25naXR1ZGUiLCB5bGFiID0gIkxhdGl0dWRlIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9iaW8vc2FtcGxpbmdpbnN0aXR1dGlvbnMvTWFpbmVETVJfb2NjdXJyZW5jZXNfYWxsLnBuZyIpICN0aGlzIHByaW50cyBhIHBuZyBvZiB0aGUgcGxvdA0KZGV2Lm9mZigpICN0aGlzIHR1cm5zIG9mZiB0aGUgcHJpbnQgY29tbWFuZA0KDQpORUZTQ19vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJORUZTQyIsIF0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM5LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiTkVGU0MgT2NjdXJyZW5jZXMiLCAgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMoTkVGU0Nfb2JzJGRlY2ltYWxMb25naXR1ZGUsIE5FRlNDX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9ORUZTQ19vY2N1cnJlbmNlc19hbGwucG5nIikgI3RoaXMgcHJpbnRzIGEgcG5nIG9mIHRoZSBwbG90DQpkZXYub2ZmKCkgI3RoaXMgdHVybnMgb2ZmIHRoZSBwcmludCBjb21tYW5kDQoNClJPTV9vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJST00iLCBdDQptYXAyIDwtIGdldE1hcChyZXNvbHV0aW9uID0gImxvdyIpICNjcmVhdGVzIGFuIG9iamVjdCBjYWxsZWQgbWFwIGF0IGxvdyByZXNvdWx0aW9uDQpwbG90KG1hcDIsIHhsaW0gPSBjKC03MCwgLTQzKSwgeWxpbSA9YygzOSwgNzApLCBhc3AgPSAxLCBtYWluID0gIlJveWFsIE9udGFyaW8gTXVzZXVtIE9jY3VycmVuY2VzIiwgIGNvbCA9ICJjb3Juc2lsayIpICN0aGUgeCBhbmQgeSBsaW0gYXJlIHRoZSBsb25nLWxhdCBib3VuZHMgb2YgdGhlIG1hcA0KcG9pbnRzKFJPTV9vYnMkZGVjaW1hbExvbmdpdHVkZSwgUk9NX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9ST01fb2NjdXJyZW5jZXNfYWxsLnBuZyIpICN0aGlzIHByaW50cyBhIHBuZyBvZiB0aGUgcGxvdA0KYGBgDQoNCiMgY2hlY2sgZm9yIGdlYXIgdHlwZQ0KDQp3aGF0IGFyZSB0aGUgdW5pcXVlIGdlYXIgdHlwZXMgeW91IGhhdmUgaW4geW91ciBwcmVzZW5jZSBkYXRhLCBhbmQgaG93IG1hbnk/DQoNCmBgYHtyIG9ic2VydmF0aW9uIGJ5IGNlbGwgLSB0b3RhbH0NCmdlYXJfY291bnQgPC0gY291bnQocHJlc2VuY2UsICJnZWFyIikNCndyaXRlLmNzdihnZWFyX2NvdW50LCBmaWxlID0gIi4uL291dHB1dC9iaW8vZ2Vhcl9jb3VudC5jc3YiKQ0KZ2Vhcl9jb3VudA0KYGBgDQoNCnNvIHRoZSB2YXN0IG1ham9yaXR5IGFyZSB0cmF3bHMgb2Ygc29tZSB0eXBlLiANCg0KbWFwIHRoZSBnZWFyIHVzYWdlIGluIEFyY2dpcyAoZ2Vhcl90eXBlX21hcCkNCg0KY3JlYXRlIGEgdGFibGUgb2YgZ2VhciB1c2UgYnkgbW9udGgNCg0KYGBge3J9DQpnZWFyYnlfbXRoIDwtIHdpdGgocHJlc2VuY2UsIHRhYmxlKG1vbnRoLCBnZWFyKSkNCndyaXRlLmNzdihnZWFyYnlfbXRoLCBmaWxlID0gIi4uL291dHB1dC9iaW8vZ2Vhcl9ieV9tdGguY3N2IikNCmdlYXJieV9tdGgNCmBgYA0KDQpXaGF0IEkgd2FudCB0byBzZWUgaWYgaWYgdGhlcmUgaXMgYSBtYXJrZWQgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBlbnYuIGNvcnJlbGF0ZXMgb2YgdGhlIHByZXNlbmNlIHBvaW50cyBiZXR3ZWVuIGdlYXIgdHlwZSB1c2VkLiBUaGlzIGlzIGFsc28gdG8gdHJ5IGRlYWwgd2l0aCBkZXRlY3Rpb24gYmlhcyBiZXR3ZWVuIGdlYXIgdHlwZSAoYi9jIHRoZSB3aG9sZSByZWdpb24gaXMgbm90IHVuaWZvcm1seSBzYW1wbGVkIGJ5IHRoZSBzYW1lIGdlYXIgdHlwZSkNCg0KZmlyc3QgY3JlYXRlIGdlYXIgZGF0YXNldHMNCg0KYGBge3IgcHJlc2VuY2UgYnkgZ2Vhcn0NCnByZXNlbmNlJGdlYXIgPC0gYXMuY2hhcmFjdGVyKHByZXNlbmNlJGdlYXIpDQpib3R0b21fdHJhd2wgPC0gc3Vic2V0KHByZXNlbmNlLCBnZWFyID09ICJib3R0b21fdHJhd2wiKQ0KYm90dG9tX3RyYXdsX2FsZnJlZG9fMDMgPC0gc3Vic2V0KHByZXNlbmNlLCBnZWFyID09ICJib3R0b21fdHJhd2xfYWxmcmVkb18wMyIpDQpib3R0b21fdHJhd2xfY2FtcGVsZW5fMTQgPC0gc3Vic2V0KHByZXNlbmNlLCBnZWFyID09ICJib3R0b21fdHJhd2xfY2FtcGVsZW5fMTQiKQ0KYm90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAgPC0gc3Vic2V0KHByZXNlbmNlLCBnZWFyID09ICJib3R0b21fdHJhd2xfY2FtcGVsZW5fMTgwMCIpDQpib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEgPC0gc3Vic2V0KHByZXNlbmNlLCBnZWFyID09ICJib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEiKQ0KYm90dG9tX3RyYXdsX2Nvc21vc18yNjAwIDwtIHN1YnNldChwcmVzZW5jZSwgZ2VhciA9PSAiYm90dG9tX3RyYXdsX2Nvc21vc18yNjAwIikNCmJvdHRvbV90cmF3bF93ZXN0ZXJuX0lJQSA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gImJvdHRvbV90cmF3bF93ZXN0ZXJuX0lJQSIpDQp1bmtub3duIDwtIHN1YnNldChwcmVzZW5jZSwgZ2VhciA9PSAidW5rbm93biIpDQp2ZXJ0aWNhbF9wbGFua3Rvbl90b3cgPC0gc3Vic2V0KHByZXNlbmNlLCBnZWFyID09ICJ2ZXJ0aWNhbF9wbGFua3Rvbl90b3ciKQ0KYGBgDQoNCnBsb3QgYnkgZWFjaCB2YXJpYWJsZSwgbGVzcyAzbSAoMiBzYW1wbGVzKSAxYyAob25lIHNhbXBsZSkgYW5kIDV6ZSAoemVybyBzYW1wbGVzPyEpDQpgYGB7ciBwcmVzZW5jZSBieSBnZWFyIGJ5IHZhcmlhYmxlfQ0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSB0ZW1wX3N1cmZhY2UsIGNvbG91ciA9IGdlYXIpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2FsZnJlZG9fMDMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTgwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jb3Ntb3NfMjYwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF93ZXN0ZXJuX0lJQSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXVua25vd24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT12ZXJ0aWNhbF9wbGFua3Rvbl90b3csIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfZ2Vhcl9wbG90cy90ZW1wX3N1cmZhY2VfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSB0ZW1wX2RlcHRoLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvdGVtcF9kZXB0aF9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IGNobF9zdXJmYWNlLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvY2hsX3N1cmZhY2VfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSBjaGxfZGVwdGgsIGNvbG91ciA9IGdlYXIpKSAgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvY2hsX2RlcHRoX2dlYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChib3R0b21fdHJhd2wsIGFlcyh4ID0gc2FsaW5pdHlfc3VyZmFjZSwgY29sb3VyID0gZ2VhcikpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfYWxmcmVkb18wMywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xODAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzIxLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2Nvc21vc18yNjAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dW5rbm93biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXZlcnRpY2FsX3BsYW5rdG9uX3RvdywgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9nZWFyX3Bsb3RzL3NhbGluaXR5X3N1cmZhY2VfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSBzYWxpbml0eV9kZXB0aCwgY29sb3VyID0gZ2VhcikpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfYWxmcmVkb18wMywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xODAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzIxLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2Nvc21vc18yNjAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dW5rbm93biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXZlcnRpY2FsX3BsYW5rdG9uX3RvdywgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9nZWFyX3Bsb3RzL3NhbGluaXR5X2RlcHRoX2dlYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChib3R0b21fdHJhd2wsIGFlcyh4ID0gbzJfc3VyZmFjZSwgY29sb3VyID0gZ2VhcikpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfYWxmcmVkb18wMywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xODAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzIxLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2Nvc21vc18yNjAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dW5rbm93biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXZlcnRpY2FsX3BsYW5rdG9uX3RvdywgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9nZWFyX3Bsb3RzL28yX3N1cmZhY2VfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSBvMl9kZXB0aCwgY29sb3VyID0gZ2VhcikpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfYWxmcmVkb18wMywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xODAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzIxLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2Nvc21vc18yNjAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dW5rbm93biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXZlcnRpY2FsX3BsYW5rdG9uX3RvdywgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9nZWFyX3Bsb3RzL28yX2RlcHRoX2dlYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChib3R0b21fdHJhd2wsIGFlcyh4ID0gbWxwX3N1cmZhY2UsIGNvbG91ciA9IGdlYXIpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2FsZnJlZG9fMDMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTgwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jb3Ntb3NfMjYwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF93ZXN0ZXJuX0lJQSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXVua25vd24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT12ZXJ0aWNhbF9wbGFua3Rvbl90b3csIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfZ2Vhcl9wbG90cy9tbHBfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSBzc2hfc3VyZmFjZSwgY29sb3VyID0gZ2VhcikpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfYWxmcmVkb18wMywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xODAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzIxLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2Nvc21vc18yNjAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dW5rbm93biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXZlcnRpY2FsX3BsYW5rdG9uX3RvdywgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9nZWFyX3Bsb3RzL3NzaF9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCg0KDQoNCg0KYGBge3J9DQpwYXIobWFyPWMoNyw1LDEsMSkpDQpib3hwbG90KHByZXNlbmNlJHRlbXBfZGVwdGggfiBwcmVzZW5jZSRnZWFyLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiBEZXB0aCBieSBnZWFyIHR5cGUiLCBsYXMgPSAyKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcGVyYXR1cmVfYm94cGxvdF9kZXB0X2dlYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KbG9va3MgbGlrZSBub3QgbXVjaCBkaWZmZXJlbmNlLi4uIHdoYXQgYWJvdXQgYSBrcnVza2FsIHdhbGxhY2UgdGVzdD8NCg0KYGBge3J9DQprcnVza2FsLnRlc3QocHJlc2VuY2UkdGVtcF9kZXB0aCB+IHByZXNlbmNlJGdlYXIpDQpgYGANCk9rIHNvIHRoZXJlIGlzIGEgc3RhdGlzdGljYWxseSBzaWcgZGlmZmVyZW5jZSBzb21ld2hlcmUgaW4gdGhlIHRlbXAgYXQgZGVwdGggcmVwb3J0ZWQgYnkgdGhlIGdlYXIgdHlwZSAoS3J1c2thbC1XYWxsaXMgY2hpLXNxdWFyZWQgPSAyNDguMjcsIGRmID0gNywgcC12YWx1ZSA8IDIuMmUtMTYpDQoNClRvIHNlZSB3aGVyZSB0aGUgZGlmZmVyZW5jZShzKSBhcmUgcnVuIGEgRHVubiB0ZXN0IFphciAoMjAxMCkgc3RhdGVzIHRoYXQgdGhlIER1bm4gdGVzdCAoaW4gdGhlIEZTQSBwYWNrYWdlKSBpcyBhcHByb3ByaWF0ZSBmb3IgZ3JvdXBzIHdpdGggdW5lcXVhbCBudW1iZXJzIG9mIG9ic2VydmF0aW9ucy4oWmFyLCBKLkguIDIwMTAuIEJpb3N0YXRpc3RpY2FsIEFuYWx5c2lzLCA1dGggZWQuICBQZWFyc29uIFByZW50aWNlIEhhbGw6IFVwcGVyIFNhZGRsZSBSaXZlciwgTkouKSBodHRwOi8vcmNvbXBhbmlvbi5vcmcvcmNvbXBhbmlvbi9kXzA2Lmh0bWwNCg0KU0FNIFdIRU4gRFVOTiBJUyBJTlNUQUxMRUQsIEdPIFRPIFJDT01QQU5JT05TLk9SRyBBTkQgTE9PSyBGT1IgRFVOTiAtIENIRUNLIENIUk9NRSBISVNUT1JZIChQUk9CQUJMWSBVTkRFUiBLUlVTS0FMIFdBTExJUykgQUxTTyBNQVAgVEhFIERJU1RSSUJVVElPTiBPRiBUSEVTRSBHRUFSIFRZUEVTDQpgYGB7cn0NCnBhaXJ3aXNlLndpbGNveC50ZXN0KHByZXNlbmNlJHRlbXBfZGVwdGgsIHByZXNlbmNlJGdlYXIsIHAuYWRqPSdib25mZXJyb25pJywgZXhhY3Q9RikNCmBgYA0KDQpkdW5uIHRlc3QgDQpgYGB7cn0NCmdlYXJfdGVtcF9kZXB0aGR1bm4gPC0gZHVublRlc3QocHJlc2VuY2UkdGVtcF9kZXB0aCwgcHJlc2VuY2UkZ2VhciwgbGlzdCA9IFRSVUUpDQpnZWFyX3RlbXBfZGVwdGhkdW5uDQoNCg0KDQp3cml0ZS5jc3YodGFibGUsICIuLi9vdXRwdXQvZW52L2dlYXJfdGVtcF9kZXB0aGR1bm4uY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCmBgYA0KDQoNCiN2aWYNCg0KZm9yIHRoaXMgeW91IG5lZWQgdGhlIGpvaW5lZCBkYXRhc2V0LiB0aGlzIHdhcyBjcmVhdGVkIHVuZGVyIG1lcmdpZ19kYXRhc2V0cy5zcmMgYW5kIHRoZSBmaWxlIGlzIC4uL291dHB1dC9iaW8vcHJlc2FiLmNzdg0KDQpgYGB7cn0NCnByZXNhYiA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby9wcmVzYWIuY3N2IiwgaGVhZGVyID0gVFJVRSkNCmBgYA0KDQoNCmBgYHtyfQ0KdmlmX2FsbHByZXNhYiA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxwcmVzYWIsICIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxwcmVzYWIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxwcmVzYWINCmBgYA0KaW50ZXJwcmV0IC0gc2VlIGh0dHBzOi8vc3RhdHMuc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzcwNjc5L3doaWNoLXZhcmlhbmNlLWluZmxhdGlvbi1mYWN0b3Itc2hvdWxkLWktYmUtdXNpbmctdGV4dGd2aWYtb3ItdGV4dGd2aWYvOTY1ODQjOTY1ODQNClRvIG1ha2UgR1ZJRnMgY29tcGFyYWJsZSBhY3Jvc3MgZGltZW5zaW9ucywgd2Ugc3VnZ2VzdGVkIHVzaW5nIEdWSUZeKDEvKDIqRGYpKSwgd2hlcmUgRGYgaXMgdGhlIG51bWJlciBvZiBjb2VmZmljaWVudHMgaW4gdGhlIHN1YnNldCAocmVmIGZveCBhbmQgbW90ZXR0ZSAxOTkyIGluIHpvdGVybykNCm9yIHRoZSAyIGNvbnRpbnVvdXMgdmFyaWFibGVzLCBHVklGy4YoMS8oMipEZikpICh3aGljaCBpcyBiYXNpY2FsbHkgdGhlIHNxdWFyZSByb290IG9mIHRoZSBWSUYvR1ZJRiB2YWx1ZSBhcyBERj0xKSBpcyB0aGUgcHJvcG9ydGlvbmFsIGNoYW5nZSBvZiB0aGUgc3RhbmRhcmQgZXJyb3IgYW5kIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgdGhlaXIgY29lZmZpY2llbnRzIGR1ZSB0byB0aGUgbGV2ZWwgb2YgY29sbGluZWFyaXR5LiBUaGUgR1ZJRsuGKDEvKDIqRGYpKSB2YWx1ZSBvZiB0aGUgY2F0ZWdvcmljYWwgdmFyaWFibGUgaXMgYSBzaW1pbGFyIG1lYXN1cmUgZm9yIHRoZSByZWR1Y3Rpb24gaW4gcHJlY2lzaW9uIG9mIHRoZSBjb2VmZmljaWVudHMnIGVzdGltYXRpb24gZHVlIHRvIGNvbGxpbmVhcml0eS4gDQphcHBhcmVudGx5IGkganVzdCBuZWVkIHRvIHNxdWFyZSBHVklGXigxLygyKkRmKSkgYW5kIHRoZW4gdXNlIHRoZSBub3JtYWwgVklGICJydWxlIG9mIHRodW1iIi4uLg0KDQpgYGB7cn0NCnZpZl9hbGxwcmVzYWJfc3EgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmX2FsbHByZXNhYi5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2FsbHByZXNhYl9zcSRHVklGMkRmc3EgPC0gdmlmX2FsbHByZXNhYl9zcSRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9hbGxwcmVzYWJfc3EsICIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxwcmVzYWJfc3EuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxwcmVzYWJfc3ENCmBgYA0KDQpBcyBwZXIgU0xSIHN1Z2dlc3Rpb24sIHJlcnVuIHdpdGhvdXQgZ2Vhcg0KDQpgYGB7ciB2aWYgYWxsIGJ1dCBnZWFyfQ0KdmlmX2FsbGJ1dGdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRnZWFyLCAiLi4vb3V0cHV0L2Jpby92aWZfYWxsYnV0Z2Vhci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dGdlYXINCmBgYA0KDQpBcyBwZXIgU0xSIHN1Z2dlc3Rpb24sIHJlcnVuIHdpdGhvdXQgZ2VhciBhbmQgbW9zdCBoaWdobHkgY29ycmVsYXRlZCB2YXJpYWJsZXMgDQoNCmBgYHtyIHZpZiB3aXRob3V0IGdlYXIgKyBoaWdoIGNvcnJ9DQp2aWZfYWxsYnV0Z2VhcmhpZ2hseWNvcnIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0Z2VhcmhpZ2hseWNvcnIsICIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRnZWFyaGlnaGx5Y29yci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dGdlYXJoaWdobHljb3JyDQpgYGANCg0KDQpBcyBwZXIgU0xSIHN1Z2dlc3Rpb24sIHJlcnVuIHdpdGggZ2VhciBidXQgd2l0aG91dCBtb3N0IGhpZ2hseSBjb3JyZWxhdGVkIHZhcmlhYmxlcw0KDQpgYGB7ciB2aWYgYWxsIGJ1dCBoaWdoIGNvcnJ9DQp2aWZfYWxsYnV0aGlnaGx5Y29yciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIgKyBnZWFyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGx5Y29yciwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dGhpZ2hseWNvcnIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRoaWdobHljb3JyDQoNCnZpZl9hbGxidXRoaWdobHljb3JyX3NxIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRoaWdobHljb3JyLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGx5Y29ycl9zcSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dGhpZ2hseWNvcnJfc3EkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGx5Y29ycl9zcSwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dGhpZ2hseWNvcnJfc3EuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRoaWdobHljb3JyX3NxDQpgYGANCg0Kb2sgcmVtb3ZlIG9uZSB2YXJpYWJsZSBhdCBhIHRpbWUgLSBsZWF2ZSBnZWFyIGluDQoNCnJlbW92ZSBhbW9fcHJldg0KYGBge3IgdmlmIGFsbCBidXQgYW1vcHJldn0NCnZpZl9hbGxidXRhbW9fcHJldiA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0YW1vX3ByZXYsICIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRhbW9fcHJldi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dGFtb19wcmV2DQoNCnZpZl9hbGxidXRhbW9fcHJldl9zcSA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWZfYWxsYnV0YW1vX3ByZXYuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9hbGxidXRhbW9fcHJldl9zcSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dGFtb19wcmV2X3NxJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGFtb19wcmV2X3NxLCAiLi4vb3V0cHV0L2Jpby92aWZfYWxsYnV0YW1vX3ByZXZfc3EuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRhbW9fcHJldl9zcQ0KYGBgDQphbmQgbGVhdmUgZ2VhciBvdXQNCg0KcmVtb3ZlIGFtb19wcmV2ICsgZ2Vhcg0KYGBge3IgdmlmIGFsbCBidXQgYW1vcHJldiArIGdlYXJ9DQp2aWZfYWxsYnV0YW1vX3ByZXZnZWFyIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGFtb19wcmV2Z2VhciwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dGFtb19wcmV2Z2Vhci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dGFtb19wcmV2Z2Vhcg0KYGBgDQoNCnJlbW92ZSBjaGxfZGVwdGgNCmBgYHtyIHZpZiBhbGwgYnV0IGNobGRlcHRofQ0KdmlmX2FsbGJ1dGNobF9kZXB0aCA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRjaGxfZGVwdGgsICIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRjaGxfZGVwdGguY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRjaGxfZGVwdGgNCg0KdmlmX2FsbGJ1dGNobF9kZXB0aF9zcSA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWZfYWxsYnV0Y2hsX2RlcHRoLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0Y2hsX2RlcHRoX3NxJEdWSUYyRGZzcSA8LSB2aWZfYWxsYnV0Y2hsX2RlcHRoX3NxJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGNobF9kZXB0aF9zcSwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dGNobF9kZXB0aF9zcS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dGNobF9kZXB0aF9zcQ0KYGBgDQoNCnJlbW92ZSBjaGxfZGVwdGggYW5kIGdlYXINCmBgYHtyIHZpZiBhbGwgYnV0IGNobGRlcHRoK2dlYXJ9DQp2aWZfYWxsYnV0Y2hsX2RlcHRoZ2VhciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGNobF9kZXB0aGdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRjaGxfZGVwdGhnZWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0Y2hsX2RlcHRoZ2Vhcg0KYGBgDQoNCg0KcmVtb3ZlIHNzaF9zdXJmYWNlDQpgYGB7ciB2aWYgYWxsIGJ1dCBzc2h9DQp2aWZfYWxsYnV0c3NoX3N1cmZhY2UgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHNzaF9zdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWZfYWxsYnV0c3NoX3N1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRzc2hfc3VyZmFjZQ0KDQp2aWZfYWxsYnV0c3NoX3N1cmZhY2Vfc3EgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dHNzaF9zdXJmYWNlLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0c3NoX3N1cmZhY2Vfc3EkR1ZJRjJEZnNxIDwtIHZpZl9hbGxidXRzc2hfc3VyZmFjZV9zcSRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9hbGxidXRzc2hfc3VyZmFjZV9zcSwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dHNzaF9zdXJmYWNlX3NxLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0c3NoX3N1cmZhY2Vfc3ENCmBgYA0KDQpyZW1vdmUgc3NoX3N1cmZhY2UgJiBnZWFyDQpgYGB7ciB2aWYgYWxsIGJ1dCBzc2grZ2Vhcn0NCnZpZl9hbGxidXRzc2hfc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0c3NoX3N1cmZhY2VnZWFyLCAiLi4vb3V0cHV0L2Jpby92aWZfYWxsYnV0c3NoX3N1cmZhY2VnZWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0c3NoX3N1cmZhY2VnZWFyDQpgYGANCg0KcmVtb3ZlIG8yX3N1cmZhY2UNCmBgYHtyIHZpZiBhbGwgYnV0IG8yc3VyZmFjZX0NCnZpZl9hbGxidXRvMl9zdXJmYWNlIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0bzJfc3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dG8yX3N1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRvMl9zdXJmYWNlDQoNCnZpZl9hbGxidXRvMl9zdXJmYWNlX3NxIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRvMl9zdXJmYWNlLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0bzJfc3VyZmFjZV9zcSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dG8yX3N1cmZhY2Vfc3EkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0bzJfc3VyZmFjZV9zcSwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dG8yX3N1cmZhY2Vfc3EuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRvMl9zdXJmYWNlX3NxDQpgYGANCg0KcmVtb3ZlIG8yX3N1cmZhY2UgJiBnZWFyDQpgYGB7ciB2aWYgYWxsIGJ1dCBvMnN1cmZhY2UrZ2Vhcn0NCnZpZl9hbGxidXRvMl9zdXJmYWNlZ2VhciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0bzJfc3VyZmFjZWdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRvMl9zdXJmYWNlZ2Vhci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dG8yX3N1cmZhY2VnZWFyDQpgYGANCg0KYXMgcGVyIFNMUiBjaGF0IGphbiAyMzogDQoNCnJlbW92ZSBzYWxpbml0eV9zdXJmYWNlIG9ubHkNCmBgYHtyIHZpZiBhbGwgYnV0IHNhbHN1cmZhY2V9DQp2aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlDQoNCnZpZl9hbGxidXRzYWxpbml0eXN1cmZhY2Vfc3EgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZS5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZV9zcSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZV9zcSRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9hbGxidXRzYWxpbml0eXN1cmZhY2Vfc3EsICIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRzYWxpbml0eXN1cmZhY2Vfc3EuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRzYWxpbml0eXN1cmZhY2Vfc3ENCmBgYA0KYW5kIHdpdGhvdXQgZ2Vhcg0KDQpgYGB7ciB2aWYgYWxsIGJ1dCBzYWxzdXJmYWNlK2dlYXJ9DQp2aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlZ2VhciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlZ2VhciwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZWdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRzYWxpbml0eXN1cmZhY2VnZWFyDQpgYGANCg0Kbm93IHJlbW92ZSB0ZW1wX3N1cmZhY2UgcGx1cyBoaWdobHkgY29ycmVsYXRlZA0KYGBge3IgdmlmIGFsbGJ1dCBoaWdoIGNvcnIgKyB0ZW1wIHN1cmZhY2UvZ2Vhci9ub2dlYXJ9DQojd2l0aCBnZWFyDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHN1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlDQoNCnZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlX3NxIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZV9zcSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHN1cmZhY2Vfc3EkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZV9zcSwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHN1cmZhY2Vfc3EuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlX3NxDQoNCiN3aXRob3V0IGdlYXINCnZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlZ2VhciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlZ2VhciwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHN1cmZhY2VnZWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZWdlYXINCmBgYA0KDQpub3cgcmVtb3ZlIHRlbXBfc3VyZmFjZSBwbHVzIHNhbGluaXR5X3N1cmZhY2UNCmBgYHtyIHZpZiBhbGxidXQgdGVtcCArIHNhbGluaXR5IHN1cmZhY2UvZ2Vhci9ub2dlYXJ9DQojd2l0aCBnZWFyDQp2aWZfYWxsYnV0dGVtcHNhbHN1cmZhY2UgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0dGVtcHNhbHN1cmZhY2UNCg0KdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlX3NxIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZS5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlX3NxJEdWSUYyRGZzcSA8LSB2aWZfYWxsYnV0dGVtcHNhbHN1cmZhY2Vfc3EkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0dGVtcHNhbHN1cmZhY2Vfc3EsICIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZV9zcS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlX3NxDQoNCiN3aXRob3V0IGdlYXINCnZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlZ2VhciwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlZ2Vhci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlZ2Vhcg0KYGBgDQoNCm5vdyByZW1vdmUgdGVtcF9zdXJmYWNlIHBsdXMgc2FsaW5pdHlfc3VyZmFjZSArIGhpZ2hseSBjb3JyZWxhdGVkDQpgYGB7ciB2aWYgYWxsYnV0IGhpZ2ggY29yciArICB0ZW1wICsgc2FsaW5pdHkgc3VyZmFjZS9nZWFyL25vZ2Vhcn0NCiN3aXRoIGdlYXINCnZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2UsICIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZQ0KDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZV9zcSA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZS5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2Vfc3EkR1ZJRjJEZnNxIDwtIHZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlX3NxJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2Vfc3EsICIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlX3NxLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZV9zcQ0KDQojd2l0aG91dCBnZWFyDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlZ2VhciwgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2VnZWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZWdlYXINCmBgYA0KDQpKdXN0IG91dCBvZiBjdXJpb3NpdHksIGEgdmlmIHdpbGwgYWxsIGJ1dCBidXQgYXRtb3MgZHJpdmVycw0KDQpgYGB7cn0NCnZpZl9hbGxidXRuYW9hbW8gPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgZ2VhciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dG5hb2FtbywgIi4uL291dHB1dC9iaW8vdmlmX2FsbGJ1dG5hb2Ftby5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dG5hb2Ftbw0KDQp2aWZfYWxsYnV0bmFvYW1vX3NxIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZl9hbGxidXRuYW9hbW8uY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9hbGxidXRuYW9hbW9fc3EkR1ZJRjJEZnNxIDwtIHZpZl9hbGxidXRuYW9hbW9fc3EkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0bmFvYW1vX3NxLCAiLi4vb3V0cHV0L2Jpby92aWZfYWxsYnV0bmFvYW1vX3NxLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0bmFvYW1vX3NxDQpgYGANCg0KIyBjaGVjayB0byBzZWUgaG93IG1hbnkgY2VsbHMgaGF2ZSA+MSBwb2ludCBwZXIgdGltZXNsaWNlDQoNCnRoaXMgbmVlZHMgdG8gYmUgM0Qgc28geW91IG5lZWQgdG8gY3JlYXRlIGEgY2VsbF9pZF8zZA0KYGBge3IgY2VsbF9pZF8zZH0NCnByZXNhYiRjZWxsX2lkXzNkIDwtIHBhc3RlKHByZXNhYiRjZWxsX2lkLCBwcmVzYWIkZGVwdGhsYXllcm5vLCBzZXA9Il8iKSAjY3JlYXRlIGEgbmV3IGNvbHVtbiB0aGF0IGlzIGEgdW5pcXVlIGNlbGxfaWQgJiBkZXB0aCBJRC4gDQpoZWFkKHByZXNhYikNCmBgYA0KYW5kIG5vdyBkbyBvbmUgd2l0aCBhIHRpbWVzbGljZSBsYWJlbA0KYGBge3IgY2VsbF9pZF94eXp0fQ0KcHJlc2FiJGNlbGxfaWRfeHl6dCA8LSBwYXN0ZShwcmVzYWIkY2VsbF9pZF8zZCwgcHJlc2FiJHllYXIsIHByZXNhYiRtb250aCwgc2VwPSJfIikgI2NyZWF0ZSBhIG5ldyBjb2x1bW4gdGhhdCBpcyBhIHVuaXF1ZSBjZWxsX2lkICYgZGVwdGggSUQuIA0KaGVhZChwcmVzYWIpDQp3cml0ZS5jc3YocHJlc2FiLCAiLi4vb3V0cHV0L2Jpby9wcmVzYWJfY2VsbGlkX3h5enQuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCg0KDQpiZWNhdXNlIGJhY2tncm91bmQgcG9pbnRzIGNhbiBsYW5kIGluIHRoZSBzYW1lIHh5enQsIHN1YnNldCB0aGUgZGF0YXNldCB0byBiZSBvbmx5IHByZXNlbmNlcw0KDQpgYGB7cn0NCnByZXNlbmNlZHVwIDwtIHN1YnNldChwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjEiKQ0KbnJvdyhwcmVzZW5jZWR1cCkNCmBgYA0KDQoNCnRoZSBkYXRhIGlzIGluIHByZXNlbmNlZHVwJHRvdGFsX2NlbGxfb2JzX3h5enQNCmBgYHtyIHVuaXF1ZV9wb2ludHBlcmNlbGx9DQp1bmlxdWVfcG9pbnRwZXJjZWxsIDwtIHVuaXF1ZShwcmVzZW5jZWR1cCR0b3RhbF9jZWxsX29ic194eXp0KQ0KdW5pcXVlX3BvaW50cGVyY2VsbA0KYGBgDQpidWdnZXIuLi4gb2sgc28gbGV0cyBkbyBhIGZyZXF1ZW5jeSB0YWJsZQ0KYGBge3IgdW5pcXVlX3BvaW50cGVyY2VsbCBmcmVxdWVuY2llc30NCnBvaW50cGVyY2VsbGNvdW50IDwtIGNvdW50KGNlbG9ic21vcmUxLCAidG90YWxfY2VsbF9vYnNfeHl6dCIpDQpwb2ludHBlcmNlbGxjb3VudCRub19jZWxscyA8LSBwb2ludHBlcmNlbGxjb3VudCRmcmVxIC8gcG9pbnRwZXJjZWxsY291bnQkdG90YWxfY2VsbF9vYnNfeHl6dA0Kd3JpdGUuY3N2KHBvaW50cGVyY2VsbGNvdW50LCBmaWxlID0gIi4uL291dHB1dC9iaW8vcG9pbnRwZXJjZWxsY291bnQuY3N2IikNCnBvaW50cGVyY2VsbGNvdW50DQpgYGANCg0Kc28gdGhlcmUgYXJlIDk0OSAzZCB0aW1lc2xpY2VkIGNlbGxzIHRoYXQgY29udGFpbiBtb3JlIHRoYW4gb25lIG9jY3VycmVuY2UsIGFuZCAyMDQyIHJvd3MuIA0KLSBkaWZmZXJlbnQgc2FtcGxpbmcgZGF5cw0KLSBkaWZmZXJlbnQgY29vcmRpbmF0ZXMNCi0gcmlzayBvZiBkdXBsaWNhdGUgZW50cmllcyAoYnV0IG9ubHkgaWYgdHdvIGluc3RpdHVpb25zIGlucHV0dGVkIHRoZSBzYW1lIGRhdGEgd2l0aCBzbGlnaHRseSBkaWZmZXJlbnQgY29vcmRpbmF0ZXMgYW5kIGRpZmZlcmVudCByZXNlcmNoIHByb2dyYW0gbmFtZXMgLSBzZWUgY2VsbDM5ODVfMThfMjAwMF83IGJlbG93IGFzIGV4YW1wbGUpDQoNCmBgYHtyfQ0KY2VsbDM5ODVfMThfMjAwMF83ICA8LSBzdWJzZXQoY2Vsb2JzbW9yZTEsIGNlbGxfaWRfeHl6dCA9PSAiMzk4NV8xOF8yMDAwXzciKQ0KY2VsbDM5ODVfMThfMjAwMF83IA0KYGBgDQoNCklkZWFsbHkgeW91IG9ubHkgd2FudCBvbmUgb2JzZXJ2YXRpb24gY2VsbCBjZWxsX2lkX3h5enQuIEZpcnN0IHNlZSBpZiBhbnkgYXJlIG1pc3NpbmcgZGVwdGggZGF0YQ0KDQpmaW5kIHRoZSBjb2x1bW4gbnVtYmVycyB0aGF0IGNvcnJlc3BvbmQgdG8gdGhlIGVudi4gZGF0YSAodXNlIGZhc3RtYXRjaCBwYWNrYWdlIGFzIGlzIHF1aWNrZXIpDQoNCmBgYHtyfQ0KZm1hdGNoKCJjaGxfc3VyZmFjZSIsIG5hbWVzKGNlbG9ic21vcmUxKSkgIzI4DQpmbWF0Y2goImNobF9kZXB0aCIsIG5hbWVzKGNlbG9ic21vcmUxKSkgIzI5DQpmbWF0Y2goIm1scF9zdXJmYWNlIiwgbmFtZXMoY2Vsb2JzbW9yZTEpKSAjMzANCmZtYXRjaCgibzJfc3VyZmFjZSIsIG5hbWVzKGNlbG9ic21vcmUxKSkgIzMxDQpmbWF0Y2goIm8yX2RlcHRoIiwgbmFtZXMoY2Vsb2JzbW9yZTEpKSAjMzINCmZtYXRjaCgic2FsaW5pdHlfc3VyZmFjZSIsIG5hbWVzKGNlbG9ic21vcmUxKSkgIzMzDQpmbWF0Y2goInNhbGluaXR5X2RlcHRoIiwgbmFtZXMoY2Vsb2JzbW9yZTEpKSAjMzQNCmZtYXRjaCgic3NoX3N1cmZhY2UiLCBuYW1lcyhjZWxvYnNtb3JlMSkpICMzNQ0KZm1hdGNoKCJ0ZW1wX3N1cmZhY2UiLCBuYW1lcyhjZWxvYnNtb3JlMSkpICMzNg0KZm1hdGNoKCJ0ZW1wX2RlcHRoIiwgbmFtZXMoY2Vsb2JzbW9yZTEpKSAjMzcNCmBgYA0KDQp0aGVuIHN1YnNldCBhbnkgd2l0aCBOQSB2YWx1ZXMNCg0KYGBge3IgY2Vsb2JzbW9yZTFfbm92YWxzfQ0KY2Vsb2JzbW9yZTFfbm92YWxzIDwtICBjZWxvYnNtb3JlMVshY29tcGxldGUuY2FzZXMoY2Vsb2JzbW9yZTFbMjg6MzddKSwgXSAjMjg6MzcgcmVwcmVzZW50IHRoZSBjb2x1bW5zIHcvIGVudi4gZGF0YQ0KbnJvdyhjZWxvYnNtb3JlMV9ub3ZhbHMpICNqdXN0IHRvIGNoZWNrIGhvdyBtYW55IHRoZXJlIGFyZSAtIDEwOTUgb3V0IG9mIDIwNDINCmBgYA0KDQpvayBhbmQgc3Vic2V0IHdpdGggYWxsIHZhbHVlcw0KDQpgYGB7ciBjZWxvYnNtb3JlMV9hbGx2YWx9DQpjZWxvYnNtb3JlMV9hbGx2YWxzIDwtIGNlbG9ic21vcmUxW2NvbXBsZXRlLmNhc2VzKGNlbG9ic21vcmUxWzI4OjM3XSksIF0gIzI4OjM3IHJlcHJlc2VudCB0aGUgY29sdW1ucyB3LyBlbnYuIGRhdGENCm5yb3coY2Vsb2JzbW9yZTFfYWxsdmFscykgIzk0NyBvdXQgb2YgMjA0Mg0KYGBgDQoNCm9rIHNvIGhvdyBtYW55IHVuaXF1ZSBjZWxscyBkbyB3ZSBoYXZlIHdpdGggY29tcGxldGUgZGF0YS4uLg0KDQpgYGB7cn0NCnBvaW50cGVyY2VsbGNvdW50X2FsbGRhdGEgPC0gY291bnQoY2Vsb2JzbW9yZTFfYWxsdmFscywgInRvdGFsX2NlbGxfb2JzX3h5enQiKQ0KcG9pbnRwZXJjZWxsY291bnRfYWxsZGF0YSRub19jZWxscyA8LSBwb2ludHBlcmNlbGxjb3VudF9hbGxkYXRhJGZyZXEgLyBwb2ludHBlcmNlbGxjb3VudF9hbGxkYXRhJHRvdGFsX2NlbGxfb2JzX3h5enQNCndyaXRlLmNzdihwb2ludHBlcmNlbGxjb3VudF9hbGxkYXRhLCBmaWxlID0gIi4uL291dHB1dC9iaW8vcG9pbnRwZXJjZWxsY291bnRfYWxsZGF0YS5jc3YiKQ0KcG9pbnRwZXJjZWxsY291bnRfYWxsZGF0YQ0KYGBgDQoNCmFuZCBzZWUgd2hpY2ggY2VsbF9pZF94eXp0IGFwcGVhciBpbiBib3RoIGNlbG9ic21vcmUxX2FsbHZhbHMgYW5kIGNlbG9ic21vcmUxX25vdmFscw0KYGBge3J9DQpjZWxvYnNtb3JlMV9hbGxub3ZhbHMgPC0gaW5uZXJfam9pbihjZWxvYnNtb3JlMV9hbGx2YWxzLCBjZWxvYnNtb3JlMV9ub3ZhbHMpDQpjZWxvYnNtb3JlMV9hbGxub3ZhbHMgDQpgYGANCk5vbmUuLi4uIHdoaWNoIGlzIGdvb2QuIEknZCBleHBlY3Qgb2JzZXJ2YXRpb25zIGluIHRoZSBzYW1lIHh5enQgdG8gaGF2ZSB0aGUgc2FtZSB2YWx1ZXMNCg0Kc28sIEkgY2FuIHN1Y2Nlc3NmdWxseSByZWR1Y2UgdGhlIG9ic2VydmF0aW9ucyBkb3duIHRvIG9uZSBwZXIgeHl6dA0KDQpgYGB7cn0NCmZtYXRjaCgiY2VsbF9pZF94eXp0IiwgbmFtZXMoY2Vsb2JzbW9yZTEpKSAjNDYNCmR1cGxpY2F0ZXNiZWdvbmUgPC0gY2Vsb2JzbW9yZTFbIWR1cGxpY2F0ZWQoY2Vsb2JzbW9yZTFbICw0Nl0pLCBdICNjcmVhdGVzIGEgZGYgd2l0aCBhbGwgZHVwbGljYXRlcyBnb25lIChub3cgMSBvYnMgcGVyIGNlbGwpDQpucm93KGR1cGxpY2F0ZXNiZWdvbmUpICM5NDkgLSBnb29kDQpwcmVzYWJub2R1cCA8LSBzdWJzZXQocHJlc2FiLCB0b3RhbF9jZWxsX29ic194eXp0ID09ICIxIikgI3JlbW92ZSBhbGwgcm93cyB0aGF0IGhhdmUgbW9yZSB0aGFuIG9uZSBvYnMNCm5yb3cocHJlc2Fibm9kdXApICMxNTQ5MzUxIC0gdGhpcyBhZGRzIHVwIA0KcHJlc2FiIDwtIHJiaW5kKHByZXNhYm5vZHVwLCBkdXBsaWNhdGVzYmVnb25lKQ0KbnJvdyhwcmVzYWIpICMxNTUwMzAwIC0gZ3JlYXQhDQoNCiNyZWNhbGN1bGF0ZSB0aGUgdG90YWxfY2VsbF9vYnNfeHl6dCBjb2x1bW4NCg0KbmFtZXMocHJlc2FiKVtuYW1lcyhwcmVzYWIpPT0idG90YWxfY2VsbF9vYnNfeHl6dCJdIDwtICJYWHRvdGFsX2NlbGxfb2JzX3h5enQiICNyZW5hbWUgY29sDQpvYnNfY2VsbF95eW1tX2RlcHRoX2R1cCA8LSBjb3VudChwcmVzYWIsIGNlbGxfaWQsIHllYXIsIG1vbnRoLCBkZXB0aGxheWVybm8pDQp0ZXN0IDwtIG1lcmdlKHByZXNhYiwgb2JzX2NlbGxfeXltbV9kZXB0aF9kdXAsIGJ5Lng9YygiY2VsbF9pZCIsICJ5ZWFyIiwgIm1vbnRoIiwgImRlcHRobGF5ZXJubyIpLCBieS55PWMoImNlbGxfaWQiLCAieWVhciIsICJtb250aCIsICJkZXB0aGxheWVybm8iKSkNCm5hbWVzKHRlc3QpW25hbWVzKHRlc3QpPT0ibiJdIDwtICJ0b3RhbF9jZWxsX29ic194eXp0IiAjcmVuYW1lIGNvbA0KDQp3cml0ZS5jc3YocHJlc2FiLCAiLi4vb3V0cHV0L2Jpby9wcmVzYWJfY2VsbGlkX3h5enRfbm9kdXAuY3N2IikNCnJtKHByZXNhYm5vZHVwLCBkdXBsaWNhdGVzYmVnb25lLCBjZWxvYnNtb3JlMSwgY2Vsb2JzbW9yZTFfbm92YWxzLCBjZWxvYnNtb3JlMV9hbGxub3ZhbHMsIGNlbG9ic21vcmUxX2FsbHZhbHMpICNqdXN0IGJlY2F1c2UgdGhleSBhcmUgYmlnaXNoIHZhcmlhYmxlcw0KYGBgDQoNCg0KDQojIG1vbnRobHkgc3BlYXJtYW5zIGNvcnJlbGF0aW9ucyBhbmQgVklGDQoNCmN1cmlvdXMgLSBkb2VzIGNvcnJlbGF0aW9ucy92aWYgYWx0ZXIgYmV0d2VlbiBtb250aHM/DQoNCkZpcnN0IHNwbGl0IHRoZSBkYXRhc2V0IGludG8gbW9udGhseQ0KDQpgYGB7ciBzdWJzZXQgbW9udGhseSBwcmVzYWJ9DQpqYW5wcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjEiKQ0KZmVicHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICIyIikNCm1hcnByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiMyIpDQphcHJwcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjQiKQ0KbWF5cHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICI1IikNCmp1bnByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiNiIpDQpqdWxwcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjciKQ0KYXVncHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICI4IikNCnNlcHByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiOSIpDQpvY3RwcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjEwIikNCm5vdnByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiMTEiKQ0KZGVjcHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICIxMiIpDQpgYGANCg0Kbm93IGdldCB0aGUgYmFja2dyb3VuZCBwb2ludHMgZm9yIGVhY2ggbW9udGggKGZvciBzcGVhcm1hbnMpDQpgYGB7ciBtb250aGx5IGJhY2tncm91bmQgcG9pbnRzfQ0KamFuYmFjayA8LSBzdWJzZXQoamFucHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCmZlYmJhY2sgPC0gc3Vic2V0KGZlYnByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQptYXJiYWNrIDwtIHN1YnNldChtYXJwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0KYXByYmFjayA8LSBzdWJzZXQoYXBycHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCm1heWJhY2sgPC0gc3Vic2V0KG1heXByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQpqdW5iYWNrIDwtIHN1YnNldChqdW5wcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0KanVsYmFjayA8LSBzdWJzZXQoanVscHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCmF1Z2JhY2sgPC0gc3Vic2V0KGF1Z3ByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQpzZXBiYWNrIDwtIHN1YnNldChzZXBwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0Kb2N0YmFjayA8LSBzdWJzZXQob2N0cHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCm5vdmJhY2sgPC0gc3Vic2V0KG5vdnByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQpkZWNiYWNrIDwtIHN1YnNldChkZWNwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0KYGBgDQoNCnJ1biB0aGUgY29ycmVsYXRpb25zIG9uIGVhY2ggbW9udGgncyBiYWNrZ3JvdW5kIHBvaW50cw0KDQpgYGB7ciBtb250aGx5IHNwZWFybWFuIGNvcnJlbGF0aW9uc30NCmphbmJhY2sgPC0gc3Vic2V0KGphbmJhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoKSkNCmphbmJhY2tfY29yIDwtIGNvcihqYW5iYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihqYW5iYWNrX2NvciwgIi4uL291dHB1dC9lbnYvamFuYmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KZmViYmFjayA8LSBzdWJzZXQoZmViYmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgpKQ0KZmViYmFja19jb3IgPC0gY29yKGZlYmJhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KGZlYmJhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9mZWJiYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQptYXJiYWNrIDwtIHN1YnNldChtYXJiYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCkpDQptYXJiYWNrX2NvciA8LSBjb3IobWFyYmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3YobWFyYmFja19jb3IsICIuLi9vdXRwdXQvZW52L21hcmJhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCmFwcmJhY2sgPC0gc3Vic2V0KGFwcmJhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoKSkNCmFwcmJhY2tfY29yIDwtIGNvcihhcHJiYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihhcHJiYWNrX2NvciwgIi4uL291dHB1dC9lbnYvYXByYmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KbWF5YmFjayA8LSBzdWJzZXQobWF5YmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgpKQ0KbWF5YmFja19jb3IgPC0gY29yKG1heWJhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KG1heWJhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9tYXliYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQpqdW5iYWNrIDwtIHN1YnNldChqdW5iYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCkpDQpqdW5iYWNrX2NvciA8LSBjb3IoanVuYmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3YoanVuYmFja19jb3IsICIuLi9vdXRwdXQvZW52L2p1bmJhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCmp1bGJhY2sgPC0gc3Vic2V0KGp1bGJhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoKSkNCmp1bGJhY2tfY29yIDwtIGNvcihqdWxiYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihqdWxiYWNrX2NvciwgIi4uL291dHB1dC9lbnYvanVsYmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KYXVnYmFjayA8LSBzdWJzZXQoYXVnYmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgpKQ0KYXVnYmFja19jb3IgPC0gY29yKGF1Z2JhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KGF1Z2JhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9hdWdiYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQpzZXBiYWNrIDwtIHN1YnNldChzZXBiYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCkpDQpzZXBiYWNrX2NvciA8LSBjb3Ioc2VwYmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3Yoc2VwYmFja19jb3IsICIuLi9vdXRwdXQvZW52L3NlcGJhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCm9jdGJhY2sgPC0gc3Vic2V0KG9jdGJhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoKSkNCm9jdGJhY2tfY29yIDwtIGNvcihvY3RiYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihvY3RiYWNrX2NvciwgIi4uL291dHB1dC9lbnYvb2N0YmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0Kbm92YmFjayA8LSBzdWJzZXQobm92YmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgpKQ0Kbm92YmFja19jb3IgPC0gY29yKG5vdmJhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KG5vdmJhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9ub3ZiYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQpkZWNiYWNrIDwtIHN1YnNldChkZWNiYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCkpDQpkZWNiYWNrX2NvciA8LSBjb3IoZGVjYmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3YoZGVjYmFja19jb3IsICIuLi9vdXRwdXQvZW52L2RlY2JhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQpgYGANCg0KDQoNCiNtYXhlbnQ/DQoNCmBgYHtyfQ0KbGlicmFyeSgicmFzdGVyIikNCmxpYnJhcnkoImRpc21vIikNCmxpYnJhcnkoInJnZW9zIikNCmBgYA0KDQo=